From 66451472518950ef263001d086f0bd497cc0da2a Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 29 Apr 2022 15:21:38 -0400 Subject: [PATCH 01/68] adjust monitor schema --- .../common/constants/monitor_defaults.ts | 17 ++++++++++------- .../common/constants/monitor_management.ts | 6 +++++- .../monitor_management/monitor_types.ts | 3 +++ .../formatters/format_configs.ts | 2 ++ .../uptime/rest/fixtures/browser_monitor.json | 3 +++ 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts index e7f79fc2086a2..821ad31d68bbe 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -58,10 +58,8 @@ export const DEFAULT_BROWSER_ADVANCED_FIELDS: BrowserAdvancedFields = { export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { ...DEFAULT_COMMON_FIELDS, - [ConfigKey.SCHEDULE]: { - unit: ScheduleUnit.MINUTES, - number: '10', - }, + [ConfigKey.CUSTOM_ID]: '', + [ConfigKey.IS_PUSH_MONITOR]: false, [ConfigKey.METADATA]: { script_source: { is_generated_script: false, @@ -70,21 +68,26 @@ export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { is_zip_url_tls_enabled: false, }, [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, + [ConfigKey.PARAMS]: '', + [ConfigKey.PORT]: undefined, + [ConfigKey.SCHEDULE]: { + unit: ScheduleUnit.MINUTES, + number: '10', + }, [ConfigKey.SOURCE_INLINE]: '', + [ConfigKey.SOURCE_PUSH]: '', [ConfigKey.SOURCE_ZIP_URL]: '', [ConfigKey.SOURCE_ZIP_USERNAME]: '', [ConfigKey.SOURCE_ZIP_PASSWORD]: '', [ConfigKey.SOURCE_ZIP_FOLDER]: '', [ConfigKey.SOURCE_ZIP_PROXY_URL]: '', - [ConfigKey.PARAMS]: '', [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, - [ConfigKey.URLS]: undefined, - [ConfigKey.PORT]: undefined, + [ConfigKey.URLS]: '', }; export const DEFAULT_HTTP_SIMPLE_FIELDS: HTTPSimpleFields = { diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index c306d939c7128..76ba2c6516392 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -11,6 +11,7 @@ export enum ConfigKey { ENABLED = 'enabled', HOSTS = 'hosts', IGNORE_HTTPS_ERRORS = 'ignore_https_errors', + IS_PUSH_MONITOR = 'is_push_monitor', JOURNEY_FILTERS_MATCH = 'filter_journeys.match', JOURNEY_FILTERS_TAGS = 'filter_journeys.tags', MAX_REDIRECTS = 'max_redirects', @@ -21,8 +22,10 @@ export enum ConfigKey { LOCATIONS = 'locations', PARAMS = 'params', PASSWORD = 'password', + PORT = 'url.port', PROXY_URL = 'proxy_url', PROXY_USE_LOCAL_RESOLVER = 'proxy_use_local_resolver', + CUSTOM_ID = 'custom_id', RESPONSE_BODY_CHECK_NEGATIVE = 'check.response.body.negative', RESPONSE_BODY_CHECK_POSITIVE = 'check.response.body.positive', RESPONSE_BODY_INDEX = 'response.include_body', @@ -37,6 +40,7 @@ export enum ConfigKey { REVISION = 'revision', SCHEDULE = 'schedule', SCREENSHOTS = 'screenshots', + SOURCE_PUSH = 'source.push.content', SOURCE_INLINE = 'source.inline.script', SOURCE_ZIP_URL = 'source.zip_url.url', SOURCE_ZIP_USERNAME = 'source.zip_url.username', @@ -58,7 +62,6 @@ export enum ConfigKey { UPLOAD_SPEED = 'throttling.upload_speed', LATENCY = 'throttling.latency', URLS = 'urls', - PORT = 'url.port', USERNAME = 'username', WAIT = 'wait', ZIP_URL_TLS_CERTIFICATE_AUTHORITIES = 'source.zip_url.ssl.certificate_authorities', @@ -80,6 +83,7 @@ export const secretKeys = [ ConfigKey.RESPONSE_HEADERS_CHECK, ConfigKey.RESPONSE_RECEIVE_CHECK, ConfigKey.SOURCE_INLINE, + ConfigKey.SOURCE_PUSH, ConfigKey.SOURCE_ZIP_USERNAME, ConfigKey.SOURCE_ZIP_PASSWORD, ConfigKey.SYNTHETICS_ARGS, diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index 0e96b8b9de6e2..a6164def72633 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -201,6 +201,8 @@ export type ThrottlingConfigKey = t.TypeOf; export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ t.interface({ + [ConfigKey.CUSTOM_ID]: t.string, + [ConfigKey.IS_PUSH_MONITOR]: t.boolean, [ConfigKey.METADATA]: MetadataCodec, [ConfigKey.SOURCE_ZIP_URL]: t.string, [ConfigKey.SOURCE_ZIP_FOLDER]: t.string, @@ -214,6 +216,7 @@ export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ export const BrowserSensitiveSimpleFieldsCodec = t.intersection([ t.interface({ [ConfigKey.SOURCE_INLINE]: t.string, + [ConfigKey.SOURCE_PUSH]: t.string, [ConfigKey.SOURCE_ZIP_USERNAME]: t.string, [ConfigKey.SOURCE_ZIP_PASSWORD]: t.string, [ConfigKey.PARAMS]: t.string, diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts index f3b9787ce628d..5e07b37e07dc9 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts @@ -17,6 +17,7 @@ const UI_KEYS_TO_SKIP = [ ConfigKey.IS_THROTTLING_ENABLED, ConfigKey.LOCATIONS, ConfigKey.REVISION, + ConfigKey.IS_PUSH_MONITOR, 'secrets', ]; @@ -45,6 +46,7 @@ export const formatMonitorConfig = (configKeys: ConfigKey[], config: Partial {\\n const response = await page.goto('https://nextjs-test-synthetics.vercel.app/api/users');\\n expect(response.status()).toEqual(200);\\n});", + "source.push.content": "", + "is_push_monitor": false, "params": "", "screenshots": "on", "synthetics_args": [], From 0609acb15fbe6b5ff16973d6d05c7f48ec3bd34b Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 29 Apr 2022 15:26:29 -0400 Subject: [PATCH 02/68] adjust secrets formatting and normalizing --- .../server/lib/requests/get_monitor.ts | 20 +++++++++++-------- .../lib/synthetics_service/utils/secrets.ts | 8 +++++++- .../synthetics_service/get_monitor.ts | 4 +--- .../apis/uptime/rest/get_monitor.ts | 1 - 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/synthetics/server/lib/requests/get_monitor.ts b/x-pack/plugins/synthetics/server/lib/requests/get_monitor.ts index f8b01b63e88e6..fa3afdf1038f9 100644 --- a/x-pack/plugins/synthetics/server/lib/requests/get_monitor.ts +++ b/x-pack/plugins/synthetics/server/lib/requests/get_monitor.ts @@ -10,8 +10,10 @@ import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin import { SyntheticsMonitorWithSecrets, EncryptedSyntheticsMonitor, + SyntheticsMonitor, } from '../../../common/runtime_types'; import { syntheticsMonitor, syntheticsMonitorType } from '../saved_objects/synthetics_monitor'; +import { normalizeSecrets } from '../synthetics_service/utils'; export const getSyntheticsMonitor = async ({ monitorId, @@ -21,20 +23,22 @@ export const getSyntheticsMonitor = async ({ monitorId: string; encryptedSavedObjectsClient: EncryptedSavedObjectsClient; savedObjectsClient: SavedObjectsClientContract; -}): Promise> => { +}): Promise> => { try { const encryptedMonitor = await savedObjectsClient.get( syntheticsMonitorType, monitorId ); - return await encryptedSavedObjectsClient.getDecryptedAsInternalUser( - syntheticsMonitor.name, - monitorId, - { - namespace: encryptedMonitor.namespaces?.[0], - } - ); + const decryptedMonitor = + await encryptedSavedObjectsClient.getDecryptedAsInternalUser( + syntheticsMonitor.name, + monitorId, + { + namespace: encryptedMonitor.namespaces?.[0], + } + ); + return normalizeSecrets(decryptedMonitor); } catch (e) { throw e; } diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/utils/secrets.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/utils/secrets.ts index 7aa7aa8f32f40..242d662600d55 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/utils/secrets.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/utils/secrets.ts @@ -8,9 +8,11 @@ import { omit, pick } from 'lodash'; import { SavedObject } from '@kbn/core/server'; import { secretKeys } from '../../../../common/constants/monitor_management'; import { + ConfigKey, SyntheticsMonitor, SyntheticsMonitorWithSecrets, } from '../../../../common/runtime_types/monitor_management'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; export function formatSecrets(monitor: SyntheticsMonitor): SyntheticsMonitorWithSecrets { const monitorWithoutSecrets = omit(monitor, secretKeys) as SyntheticsMonitorWithSecrets; @@ -25,11 +27,15 @@ export function formatSecrets(monitor: SyntheticsMonitor): SyntheticsMonitorWith export function normalizeSecrets( monitor: SavedObject ): SavedObject { - return { + const defaultFields = DEFAULT_FIELDS[monitor.attributes[ConfigKey.MONITOR_TYPE]]; + const normalizedMonitor = { ...monitor, attributes: { + ...defaultFields, ...monitor.attributes, ...JSON.parse(monitor.attributes.secrets || ''), }, }; + delete normalizedMonitor.attributes.secrets; + return normalizedMonitor; } diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/get_monitor.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/get_monitor.ts index 556741c99f599..7018d50d82821 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/get_monitor.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/get_monitor.ts @@ -12,7 +12,6 @@ import { UMRestApiRouteFactory } from '../types'; import { API_URLS } from '../../../common/constants'; import { syntheticsMonitorType } from '../../lib/saved_objects/synthetics_monitor'; import { getMonitorNotFoundResponse } from './service_errors'; -import { normalizeSecrets } from '../../lib/synthetics_service/utils/secrets'; export const getSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', @@ -31,12 +30,11 @@ export const getSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMServerL const { monitorId } = request.params; const encryptedSavedObjectsClient = encryptedSavedObjects.getClient(); try { - const monitorWithSecrets = await libs.requests.getSyntheticsMonitor({ + return await libs.requests.getSyntheticsMonitor({ monitorId, encryptedSavedObjectsClient, savedObjectsClient, }); - return normalizeSecrets(monitorWithSecrets); } catch (getErr) { if (SavedObjectsErrorHelpers.isNotFoundError(getErr)) { return getMonitorNotFoundResponse(response, monitorId); diff --git a/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts index 0fa5ed26b791e..e0c4e3b2fcdd5 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts @@ -97,7 +97,6 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.body.attributes).eql({ ...monitors[0], revision: 1, - secrets: formatSecrets(monitors[0]).secrets, }); }); From 98ef4134f83b417e13f7b70d3f395988ac694a44 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 29 Apr 2022 15:30:35 -0400 Subject: [PATCH 03/68] adjust telemetry --- .../telemetry/monitor_upgrade_sender.test.ts | 70 ++++++++++--------- .../telemetry/monitor_upgrade_sender.ts | 27 +++---- 2 files changed, 53 insertions(+), 44 deletions(-) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/telemetry/monitor_upgrade_sender.test.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/telemetry/monitor_upgrade_sender.test.ts index 9d8161b02b634..9b404631a8b7d 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/telemetry/monitor_upgrade_sender.test.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/telemetry/monitor_upgrade_sender.test.ts @@ -14,6 +14,7 @@ import { DataStream, ScheduleUnit, } from '../../../../common/runtime_types/monitor_management'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; import type { TelemetryEventsSender } from '../../../lib/telemetry/sender'; import { createMockTelemetryEventsSender } from '../../../lib/telemetry/__mocks__'; @@ -42,6 +43,7 @@ const testConfig: SavedObject = { updated_at: '2011-10-05T14:48:00.000Z', id, attributes: { + ...DEFAULT_FIELDS[DataStream.BROWSER], [ConfigKey.MONITOR_TYPE]: DataStream.HTTP, [ConfigKey.LOCATIONS]: [ { @@ -103,39 +105,43 @@ describe('monitor upgrade telemetry helpers', () => { }); it.each([ - [ConfigKey.SOURCE_INLINE, 'recorder', true], - [ConfigKey.SOURCE_INLINE, 'inline', false], - [ConfigKey.SOURCE_ZIP_URL, 'zip', false], - ])('handles formatting scriptType for browser monitors', (config, scriptType, isRecorder) => { - const actual = formatTelemetryEvent({ - monitor: createTestConfig({ - [config]: 'test', - [ConfigKey.METADATA]: { - script_source: { - is_generated_script: isRecorder, + [ConfigKey.IS_PUSH_MONITOR, 'push', false, true], + [ConfigKey.SOURCE_INLINE, 'recorder', true, 'test'], + [ConfigKey.SOURCE_INLINE, 'inline', false, 'test'], + [ConfigKey.SOURCE_ZIP_URL, 'zip', false, 'test'], + ])( + 'handles formatting scriptType for browser monitors', + (config, scriptType, isRecorder, content) => { + const actual = formatTelemetryEvent({ + monitor: createTestConfig({ + [config]: content, + [ConfigKey.METADATA]: { + script_source: { + is_generated_script: isRecorder, + }, }, - }, - }), - kibanaVersion, - errors, - }); - expect(actual).toEqual({ - stackVersion: kibanaVersion, - configId: sha256.create().update(testConfig.id).hex(), - locations: ['us_central', 'other'], - locationsCount: 2, - monitorNameLength: testConfig.attributes[ConfigKey.NAME].length, - updatedAt: testConfig.updated_at, - type: testConfig.attributes[ConfigKey.MONITOR_TYPE], - scriptType, - monitorInterval: 180000, - lastUpdatedAt: undefined, - deletedAt: undefined, - errors, - durationSinceLastUpdated: undefined, - revision: 1, - }); - }); + }), + kibanaVersion, + errors, + }); + expect(actual).toEqual({ + stackVersion: kibanaVersion, + configId: sha256.create().update(testConfig.id).hex(), + locations: ['us_central', 'other'], + locationsCount: 2, + monitorNameLength: testConfig.attributes[ConfigKey.NAME].length, + updatedAt: testConfig.updated_at, + type: testConfig.attributes[ConfigKey.MONITOR_TYPE], + scriptType, + monitorInterval: 180000, + lastUpdatedAt: undefined, + deletedAt: undefined, + errors, + durationSinceLastUpdated: undefined, + revision: 1, + }); + } + ); it('handles formatting update events', () => { const actual = formatTelemetryUpdateEvent( diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/telemetry/monitor_upgrade_sender.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/telemetry/monitor_upgrade_sender.ts index 526e40ef2f230..dade0ed7475f6 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/telemetry/monitor_upgrade_sender.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/telemetry/monitor_upgrade_sender.ts @@ -134,17 +134,20 @@ export function formatTelemetryDeleteEvent( function getScriptType( attributes: Partial -): 'inline' | 'recorder' | 'zip' | undefined { - if (attributes[ConfigKey.SOURCE_ZIP_URL]) { - return 'zip'; - } else if ( - attributes[ConfigKey.SOURCE_INLINE] && - attributes[ConfigKey.METADATA]?.script_source?.is_generated_script - ) { - return 'recorder'; - } else if (attributes[ConfigKey.SOURCE_INLINE]) { - return 'inline'; +): 'inline' | 'recorder' | 'zip' | 'push' | undefined { + switch (true) { + case Boolean(attributes[ConfigKey.SOURCE_ZIP_URL]): + return 'zip'; + case Boolean( + attributes[ConfigKey.SOURCE_INLINE] && + attributes[ConfigKey.METADATA]?.script_source?.is_generated_script + ): + return 'recorder'; + case Boolean(attributes[ConfigKey.SOURCE_INLINE]): + return 'inline'; + case Boolean(attributes[ConfigKey.IS_PUSH_MONITOR]): + return 'push'; + default: + return undefined; } - - return undefined; } From 8bf704ef89e374276e946b3bf9ad40c2b976ebf0 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 29 Apr 2022 15:38:03 -0400 Subject: [PATCH 04/68] adjust monitor validation tests --- .../rest_api/synthetics_service/monitor_validation.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.test.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.test.ts index f32084756cf5e..b29754649c960 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.test.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.test.ts @@ -160,8 +160,11 @@ describe('validateMonitor', () => { testBrowserSimpleFields = { ...testZipUrlTLSFields, ...testCommonFields, + [ConfigKey.IS_PUSH_MONITOR]: false, + [ConfigKey.CUSTOM_ID]: '', [ConfigKey.METADATA]: testMetaData, [ConfigKey.SOURCE_INLINE]: '', + [ConfigKey.SOURCE_PUSH]: '', [ConfigKey.SOURCE_ZIP_URL]: '', [ConfigKey.SOURCE_ZIP_FOLDER]: '', [ConfigKey.SOURCE_ZIP_USERNAME]: 'test-username', From dead4ff32aa5fe09dbb9447b94330cceebac344d Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 29 Apr 2022 15:51:16 -0400 Subject: [PATCH 05/68] adjust imports --- .../server/lib/synthetics_service/utils/index.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 x-pack/plugins/synthetics/server/lib/synthetics_service/utils/index.ts diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/utils/index.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/utils/index.ts new file mode 100644 index 0000000000000..7fb84ce480a91 --- /dev/null +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/utils/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './secrets'; From b5403b439440ab33022ccf8431a45034f26fd97d Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 29 Apr 2022 16:32:39 -0400 Subject: [PATCH 06/68] adjust telemetry types --- x-pack/plugins/synthetics/server/lib/telemetry/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/lib/telemetry/types.ts b/x-pack/plugins/synthetics/server/lib/telemetry/types.ts index 59d060c2f3a76..4ee19b34c1f26 100644 --- a/x-pack/plugins/synthetics/server/lib/telemetry/types.ts +++ b/x-pack/plugins/synthetics/server/lib/telemetry/types.ts @@ -17,7 +17,7 @@ export interface MonitorUpdateEvent { monitorInterval: number; locations: string[]; locationsCount: number; - scriptType?: 'inline' | 'recorder' | 'zip'; + scriptType?: 'inline' | 'recorder' | 'zip' | 'push'; revision?: number; errors?: ServiceLocationErrors; configId: string; From a826d3025c62ce5a8612d81686105c140ddb8b2e Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 29 Apr 2022 16:39:04 -0400 Subject: [PATCH 07/68] add push browser monitor types --- .../runtime_types/monitor_management/index.ts | 1 + .../monitor_management/monitor_types_push.ts | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/index.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/index.ts index 94d153d56caa2..70eebae261743 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/index.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/index.ts @@ -10,4 +10,5 @@ export * from './config_key'; export * from './monitor_configs'; export * from './monitor_meta_data'; export * from './monitor_types'; +export * from './monitor_types_push'; export * from './locations'; diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts new file mode 100644 index 0000000000000..05ba1f4463154 --- /dev/null +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts @@ -0,0 +1,37 @@ +/* + * 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 * as t from 'io-ts'; +import { ScreenshotOptionCodec } from './monitor_configs'; + +export const PublicThrottlingConfigCodec = t.interface({ + download: t.number, + upload: t.number, + latency: t.number, +}); + +export const PushBrowserMonitorCodec = t.intersection([ + t.interface({ id: t.string, name: t.string, schedule: t.string, content: t.string }), + t.partial({ + locations: t.array(t.string), + throttling: PublicThrottlingConfigCodec, + screenshots: ScreenshotOptionCodec, + tags: t.array(t.string), + ignoreHTTPSErrors: t.boolean, + apmServiceName: t.string, + }), +]); + +export const PushMonitorsRequestCodec = t.interface({ + monitors: PushBrowserMonitorCodec, +}); + +export type PublicThrottlingConfig = t.TypeOf; + +export type PublicBrowserMonitor = t.TypeOf; + +export type PushMonitorsRequest = t.TypeOf; From 96f87b5debff98a0286a993b3ae665a30067b201 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 29 Apr 2022 16:44:03 -0400 Subject: [PATCH 08/68] export add and edit monitor helpers --- .../synthetics_service/add_monitor.ts | 49 ++++++++----- .../synthetics_service/edit_monitor.ts | 71 ++++++++++++------- 2 files changed, 80 insertions(+), 40 deletions(-) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor.ts index 598328349227d..02650c7fd9f1f 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor.ts @@ -17,6 +17,7 @@ import { syntheticsMonitorType } from '../../lib/saved_objects/synthetics_monito import { validateMonitor } from './monitor_validation'; import { sendTelemetryEvents, formatTelemetryEvent } from './telemetry/monitor_upgrade_sender'; import { formatSecrets } from '../../lib/synthetics_service/utils/secrets'; +import type { UptimeServerSetup } from '../../lib/adapters/framework'; export const addSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ method: 'POST', @@ -43,22 +44,7 @@ export const addSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ }) ); - const { syntheticsService } = server; - - const errors = await syntheticsService.addConfig({ - ...monitor, - id: newMonitor.id, - fields: { - config_id: newMonitor.id, - }, - fields_under_root: true, - }); - - sendTelemetryEvents( - server.logger, - server.telemetry, - formatTelemetryEvent({ monitor: newMonitor, errors, kibanaVersion: server.kibanaVersion }) - ); + const errors = await syncNewMonitor({ monitor, monitorSavedObject: newMonitor, server }); if (errors && errors.length > 0) { return response.ok({ @@ -69,3 +55,34 @@ export const addSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ return response.ok({ body: newMonitor }); }, }); + +export const syncNewMonitor = async ({ + monitor, + monitorSavedObject, + server, +}: { + monitor: SyntheticsMonitor; + monitorSavedObject: SavedObject; + server: UptimeServerSetup; +}) => { + const errors = await server.syntheticsService.addConfig({ + ...monitor, + id: monitorSavedObject.id, + fields: { + config_id: monitorSavedObject.id, + }, + fields_under_root: true, + }); + + sendTelemetryEvents( + server.logger, + server.telemetry, + formatTelemetryEvent({ + monitor: monitorSavedObject, + errors, + kibanaVersion: server.kibanaVersion, + }) + ); + + return errors; +}; diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/edit_monitor.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/edit_monitor.ts index 55be289f7162a..687a472e69704 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/edit_monitor.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/edit_monitor.ts @@ -28,6 +28,7 @@ import { formatTelemetryUpdateEvent, } from './telemetry/monitor_upgrade_sender'; import { formatSecrets, normalizeSecrets } from '../../lib/synthetics_service/utils/secrets'; +import type { UptimeServerSetup } from '../../lib/adapters/framework'; // Simplify return promise type and type it with runtime_types export const editSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ @@ -39,12 +40,8 @@ export const editSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ }), body: schema.any(), }, - handler: async ({ - request, - response, - savedObjectsClient, - server: { encryptedSavedObjects, syntheticsService, logger, telemetry, kibanaVersion }, - }): Promise => { + handler: async ({ request, response, savedObjectsClient, server }): Promise => { + const { encryptedSavedObjects, logger } = server; const encryptedSavedObjectsClient = encryptedSavedObjects.getClient(); const monitor = request.body as SyntheticsMonitor; const { monitorId } = request.params; @@ -84,29 +81,19 @@ export const editSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ revision: (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1, }); - const editMonitor: SavedObjectsUpdateResponse = + const editedMonitorSavedObject: SavedObjectsUpdateResponse = await savedObjectsClient.update( syntheticsMonitorType, monitorId, monitor.type === 'browser' ? { ...monitorWithRevision, urls: '' } : monitorWithRevision ); - const errors = await syntheticsService.pushConfigs([ - { - ...editedMonitor, - id: editMonitor.id, - fields: { - config_id: editMonitor.id, - }, - fields_under_root: true, - }, - ]); - - sendTelemetryEvents( - logger, - telemetry, - formatTelemetryUpdateEvent(editMonitor, previousMonitor, kibanaVersion, errors) - ); + const errors = await syncEditedMonitor({ + server, + editedMonitor, + editedMonitorSavedObject, + previousMonitor, + }); // Return service sync errors in OK response if (errors && errors.length > 0) { @@ -115,7 +102,7 @@ export const editSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ }); } - return editMonitor; + return editedMonitorSavedObject; } catch (updateErr) { if (SavedObjectsErrorHelpers.isNotFoundError(updateErr)) { return getMonitorNotFoundResponse(response, monitorId); @@ -126,3 +113,39 @@ export const editSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ } }, }); + +export const syncEditedMonitor = async ({ + editedMonitor, + editedMonitorSavedObject, + previousMonitor, + server, +}: { + editedMonitor: SyntheticsMonitor; + editedMonitorSavedObject: SavedObjectsUpdateResponse; + previousMonitor: SavedObject; + server: UptimeServerSetup; +}) => { + const errors = await server.syntheticsService.pushConfigs([ + { + ...editedMonitor, + id: editedMonitorSavedObject.id, + fields: { + config_id: editedMonitorSavedObject.id, + }, + fields_under_root: true, + }, + ]); + + sendTelemetryEvents( + server.logger, + server.telemetry, + formatTelemetryUpdateEvent( + editedMonitorSavedObject, + previousMonitor, + server.kibanaVersion, + errors + ) + ); + + return errors; +}; From 9071b4066d22b1d9c7bdd5dc90eadb995c750bff Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 2 May 2022 11:53:38 -0400 Subject: [PATCH 09/68] add push monitor api --- .../synthetics/common/constants/rest_api.ts | 3 + .../monitor_management/monitor_types.ts | 2 +- .../monitor_management/monitor_types_push.ts | 10 +- .../lib/saved_objects/synthetics_monitor.ts | 3 + .../normalizers/browser.test.ts | 153 ++++++++++++++ .../synthetics_service/normalizers/browser.ts | 108 ++++++++++ .../synthetics_service/synthetics_service.ts | 2 +- .../synthetics/server/rest_api/index.ts | 2 + .../synthetics_service/add_monitor_push.ts | 188 ++++++++++++++++++ .../synthetics_service/get_monitor.ts | 5 +- .../apis/uptime/rest/add_monitor_push.ts | 123 ++++++++++++ .../rest/fixtures/push_browser_monitor.json | 22 ++ .../api_integration/apis/uptime/rest/index.ts | 1 + 13 files changed, 613 insertions(+), 9 deletions(-) create mode 100644 x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts create mode 100644 x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts create mode 100644 x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts create mode 100644 x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts create mode 100644 x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json diff --git a/x-pack/plugins/synthetics/common/constants/rest_api.ts b/x-pack/plugins/synthetics/common/constants/rest_api.ts index fba2c2b750a4a..b024e0342b672 100644 --- a/x-pack/plugins/synthetics/common/constants/rest_api.ts +++ b/x-pack/plugins/synthetics/common/constants/rest_api.ts @@ -44,4 +44,7 @@ export enum API_URLS { RUN_ONCE_MONITOR = '/internal/uptime/service/monitors/run_once', TRIGGER_MONITOR = '/internal/uptime/service/monitors/trigger', SERVICE_ALLOWED = '/internal/uptime/service/allowed', + + // Service end points public + SYNTHETICS_MONITORS_PUSH = '/api/synthetics/service/push/monitors', } diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index a6164def72633..0828ba144648d 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -74,6 +74,7 @@ export const CommonFieldsCodec = t.intersection([ [ConfigKey.LOCATIONS]: MonitorServiceLocationsCodec, }), t.partial({ + [ConfigKey.CUSTOM_ID]: t.string, [ConfigKey.TIMEOUT]: t.union([t.string, t.null]), [ConfigKey.REVISION]: t.number, }), @@ -201,7 +202,6 @@ export type ThrottlingConfigKey = t.TypeOf; export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ t.interface({ - [ConfigKey.CUSTOM_ID]: t.string, [ConfigKey.IS_PUSH_MONITOR]: t.boolean, [ConfigKey.METADATA]: MetadataCodec, [ConfigKey.SOURCE_ZIP_URL]: t.string, diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts index 05ba1f4463154..86a4d003d56f1 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts @@ -8,7 +8,7 @@ import * as t from 'io-ts'; import { ScreenshotOptionCodec } from './monitor_configs'; -export const PublicThrottlingConfigCodec = t.interface({ +export const PushMonitorThrottlingConfigCodec = t.interface({ download: t.number, upload: t.number, latency: t.number, @@ -18,7 +18,7 @@ export const PushBrowserMonitorCodec = t.intersection([ t.interface({ id: t.string, name: t.string, schedule: t.string, content: t.string }), t.partial({ locations: t.array(t.string), - throttling: PublicThrottlingConfigCodec, + throttling: PushMonitorThrottlingConfigCodec, screenshots: ScreenshotOptionCodec, tags: t.array(t.string), ignoreHTTPSErrors: t.boolean, @@ -27,11 +27,11 @@ export const PushBrowserMonitorCodec = t.intersection([ ]); export const PushMonitorsRequestCodec = t.interface({ - monitors: PushBrowserMonitorCodec, + monitors: t.array(PushBrowserMonitorCodec), }); -export type PublicThrottlingConfig = t.TypeOf; +export type PushMonitorThrottlingConfig = t.TypeOf; -export type PublicBrowserMonitor = t.TypeOf; +export type PushBrowserMonitor = t.TypeOf; export type PushMonitorsRequest = t.TypeOf; diff --git a/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts b/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts index 19a975607a59a..7d1865ddc8bbc 100644 --- a/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts +++ b/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts @@ -44,6 +44,9 @@ export const syntheticsMonitor: SavedObjectsType = { }, }, }, + custom_id: { + type: 'keyword', + }, }, }, management: { diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts new file mode 100644 index 0000000000000..2803a64e0501d --- /dev/null +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts @@ -0,0 +1,153 @@ +/* + * 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, + ScreenshotOption, + Locations, + PushBrowserMonitor, +} from '../../../../common/runtime_types'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; +import { normalizePushedMonitors } from './browser'; + +describe('browser normalizers', () => { + describe('normalize push monitors', () => { + const locations: Locations = [ + { + id: 'us_central', + label: 'Test Location', + geo: { lat: 33.333, lon: 73.333 }, + url: 'test-url', + isServiceManaged: true, + }, + { + id: 'us_east', + label: 'Test Location', + geo: { lat: 33.333, lon: 73.333 }, + url: 'test-url', + isServiceManaged: true, + }, + ]; + const monitors: PushBrowserMonitor[] = [ + { + id: 'test-id-1', + screenshots: ScreenshotOption.OFF, + name: 'test-name-1', + content: 'test content 1', + schedule: '3m', + throttling: { + latency: 20, + upload: 10, + download: 5, + }, + locations: ['US Central'], + tags: ['tag1', 'tag2'], + ignoreHTTPSErrors: true, + apmServiceName: 'cart-service', + }, + { + id: 'test-id-2', + screenshots: ScreenshotOption.ON, + name: 'test-name-2', + content: 'test content 2', + schedule: '10m', + throttling: { + latency: 18, + upload: 15, + download: 10, + }, + locations: ['US Central', 'US East'], + tags: ['tag3', 'tag4'], + ignoreHTTPSErrors: false, + apmServiceName: 'bean-service', + }, + ]; + + it('properly normalizes browser monitor', () => { + const actual = normalizePushedMonitors({ locations, monitors }); + expect(actual).toEqual([ + { + ...DEFAULT_FIELDS[DataStream.BROWSER], + custom_id: 'test-id-1', + ignore_https_errors: true, + is_push_monitor: true, + locations: [ + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_central', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + }, + ], + name: 'test-name-1', + schedule: { + number: '3', + unit: 'm', + }, + screenshots: 'off', + 'service.name': 'cart-service', + 'source.push.content': 'test content 1', + tags: ['tag1', 'tag2'], + 'throttling.config': '5d/10u/20l', + 'throttling.download_speed': '5', + 'throttling.is_enabled': true, + 'throttling.latency': '20', + 'throttling.upload_speed': '10', + type: 'browser', + }, + { + ...DEFAULT_FIELDS[DataStream.BROWSER], + custom_id: 'test-id-2', + ignore_https_errors: false, + is_push_monitor: true, + locations: [ + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_central', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + }, + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_east', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + }, + ], + name: 'test-name-2', + params: '', + schedule: { + number: '10', + unit: 'm', + }, + screenshots: 'on', + 'service.name': 'bean-service', + 'source.push.content': 'test content 2', + tags: ['tag3', 'tag4'], + 'throttling.config': '10d/15u/18l', + 'throttling.download_speed': '10', + 'throttling.is_enabled': true, + 'throttling.latency': '18', + 'throttling.upload_speed': '15', + type: 'browser', + }, + ]); + }); + }); +}); diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts new file mode 100644 index 0000000000000..114886fde91df --- /dev/null +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts @@ -0,0 +1,108 @@ +/* + * 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 { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; + +import { + BrowserFields, + ConfigKey, + DataStream, + Locations, + PushBrowserMonitor, + ScheduleUnit, +} from '../../../../common/runtime_types/monitor_management'; + +/* Represents all of the push-monitor related fields that need to be + * normalized. Excludes fields that we do not support for push monitors + * This type ensures that contributors remember to add normalizers for push + * monitors where appropriate when new keys are added to browser montiors */ +type NormalizedPublicFields = Omit< + BrowserFields, + | ConfigKey.METADATA + | ConfigKey.SOURCE_INLINE + | ConfigKey.SOURCE_ZIP_URL + | ConfigKey.SOURCE_ZIP_USERNAME + | ConfigKey.SOURCE_ZIP_PASSWORD + | ConfigKey.SOURCE_ZIP_FOLDER + | ConfigKey.SOURCE_ZIP_PROXY_URL + | ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES + | ConfigKey.ZIP_URL_TLS_CERTIFICATE + | ConfigKey.ZIP_URL_TLS_KEY + | ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE + | ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE + | ConfigKey.ZIP_URL_TLS_VERSION + | ConfigKey.JOURNEY_FILTERS_MATCH + | ConfigKey.JOURNEY_FILTERS_TAGS + | ConfigKey.PARAMS + | ConfigKey.SYNTHETICS_ARGS + | ConfigKey.PORT + | ConfigKey.URLS + | ConfigKey.ENABLED // should we allow enabled? + | ConfigKey.NAMESPACE // should we allow namespace? +>; + +export const normalizePushedMonitor = ({ + locations = [], + monitor, +}: { + locations: Locations; + monitor: PushBrowserMonitor; +}): BrowserFields => { + const defaultFields = DEFAULT_FIELDS[DataStream.BROWSER]; + const normalizedFields: NormalizedPublicFields = { + [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, + [ConfigKey.IS_PUSH_MONITOR]: true, + [ConfigKey.NAME]: monitor.name || '', + [ConfigKey.SCHEDULE]: { + number: `${new RegExp(/\d+/, 'g').exec(monitor.schedule)}` || '', + unit: ScheduleUnit.MINUTES, + }, + [ConfigKey.CUSTOM_ID]: monitor.id || defaultFields[ConfigKey.CUSTOM_ID], + [ConfigKey.SOURCE_PUSH]: monitor.content || defaultFields[ConfigKey.SOURCE_PUSH], + [ConfigKey.LOCATIONS]: monitor.locations + ?.map((key) => { + return locations.find( + (location) => location.id.replace('_', ' ').toLowerCase() === key.toLowerCase() + ); + }) + .filter((location) => location !== undefined) as BrowserFields[ConfigKey.LOCATIONS], + [ConfigKey.THROTTLING_CONFIG]: monitor.throttling + ? `${monitor.throttling.download}d/${monitor.throttling.upload}u/${monitor.throttling.latency}l` + : defaultFields[ConfigKey.THROTTLING_CONFIG], + [ConfigKey.DOWNLOAD_SPEED]: `${ + monitor.throttling?.download || defaultFields[ConfigKey.DOWNLOAD_SPEED] + }`, + [ConfigKey.UPLOAD_SPEED]: `${ + monitor.throttling?.upload || defaultFields[ConfigKey.UPLOAD_SPEED] + }`, + [ConfigKey.IS_THROTTLING_ENABLED]: + Boolean(monitor.throttling) || defaultFields[ConfigKey.IS_THROTTLING_ENABLED], + [ConfigKey.LATENCY]: `${monitor.throttling?.latency || defaultFields[ConfigKey.LATENCY]}`, + [ConfigKey.APM_SERVICE_NAME]: + monitor.apmServiceName || defaultFields[ConfigKey.APM_SERVICE_NAME], + [ConfigKey.IGNORE_HTTPS_ERRORS]: + monitor.ignoreHTTPSErrors || defaultFields[ConfigKey.IGNORE_HTTPS_ERRORS], + [ConfigKey.SCREENSHOTS]: monitor.screenshots || defaultFields[ConfigKey.SCREENSHOTS], + [ConfigKey.TAGS]: monitor.tags || defaultFields[ConfigKey.TAGS], + }; + return { + ...DEFAULT_FIELDS[DataStream.BROWSER], + ...normalizedFields, + }; +}; + +export const normalizePushedMonitors = ({ + locations = [], + monitors = [], +}: { + locations: Locations; + monitors: PushBrowserMonitor[]; +}) => { + return monitors.map((monitor) => { + return normalizePushedMonitor({ monitor, locations }); + }); +}; diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts index 083f0d9f6126c..ebeee9c8937a6 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts @@ -397,7 +397,7 @@ export class SyntheticsService { return (monitors ?? []).map((monitor) => ({ ...normalizeSecrets(monitor).attributes, - id: monitor.id, + id: monitor.attributes.custom_id || monitor.id, fields_under_root: true, fields: { config_id: monitor.id }, })); diff --git a/x-pack/plugins/synthetics/server/rest_api/index.ts b/x-pack/plugins/synthetics/server/rest_api/index.ts index b95e929416713..d7a2b6ea3df82 100644 --- a/x-pack/plugins/synthetics/server/rest_api/index.ts +++ b/x-pack/plugins/synthetics/server/rest_api/index.ts @@ -34,6 +34,7 @@ import { getSyntheticsMonitorRoute, } from './synthetics_service/get_monitor'; import { addSyntheticsMonitorRoute } from './synthetics_service/add_monitor'; +import { addPublicSyntheticsMonitorRoute } from './synthetics_service/add_monitor_push'; import { editSyntheticsMonitorRoute } from './synthetics_service/edit_monitor'; import { deleteSyntheticsMonitorRoute } from './synthetics_service/delete_monitor'; import { runOnceSyntheticsMonitorRoute } from './synthetics_service/run_once_monitor'; @@ -51,6 +52,7 @@ export { uptimeRouteWrapper } from './uptime_route_wrapper'; export const restApiRoutes: UMRestApiRouteFactory[] = [ addSyntheticsMonitorRoute, + addPublicSyntheticsMonitorRoute, getSyntheticsEnablementRoute, createGetPingsRoute, createGetIndexStatusRoute, diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts new file mode 100644 index 0000000000000..99640c6d63c99 --- /dev/null +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -0,0 +1,188 @@ +/* + * 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 { isEqual } from 'lodash'; +import { schema } from '@kbn/config-schema'; +import { + SavedObjectsUpdateResponse, + SavedObjectsClientContract, + SavedObjectsFindResult, +} from '@kbn/core/server'; +import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; +import { UMServerLibs } from '../../lib/lib'; +import { + BrowserFields, + ConfigKey, + MonitorFields, + SyntheticsMonitorWithSecrets, + EncryptedSyntheticsMonitor, + ServiceLocationErrors, + PushBrowserMonitor, + Locations, +} from '../../../common/runtime_types'; +import { + syntheticsMonitorType, + syntheticsMonitor, +} from '../../lib/saved_objects/synthetics_monitor'; +import { UMRestApiRouteFactory } from '../types'; +import { API_URLS } from '../../../common/constants'; +import { getServiceLocations } from '../../lib/synthetics_service/get_service_locations'; +import { normalizePushedMonitor } from '../../lib/synthetics_service/normalizers/browser'; +import { formatSecrets, normalizeSecrets } from '../../lib/synthetics_service/utils/secrets'; +import { UptimeServerSetup } from '../../lib/adapters/framework'; +import { syncNewMonitor } from './add_monitor'; +import { syncEditedMonitor } from './edit_monitor'; + +export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ + method: 'PUT', + path: API_URLS.SYNTHETICS_MONITORS_PUSH, + validate: { + body: schema.any(), + }, + handler: async ({ request, response, savedObjectsClient, server }): Promise => { + const monitors = (request.body?.monitors as PushBrowserMonitor[]) || []; + const locations: Locations = (await getServiceLocations(server)).locations; + const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); + const createdMonitors: string[] = []; + const updatedMonitors: string[] = []; + const failedMonitors: string[] = []; + + await Promise.all( + monitors.map((monitor) => + configurePushMonitors({ + savedObjectsClient, + encryptedSavedObjectsClient, + locations, + monitor, + createdMonitors, + updatedMonitors, + failedMonitors, + server, + }) + ) + ); + + return response.ok({ + body: { + createdMonitors, + failedMonitors, + updatedMonitors, + }, + }); + }, +}); + +const getExistingMonitor = async ( + savedObjectsClient: SavedObjectsClientContract, + id: string +): Promise> => { + const { saved_objects: savedObjects } = await savedObjectsClient.find( + { + type: syntheticsMonitorType, + perPage: 1, + filter: `${syntheticsMonitorType}.attributes.${ConfigKey.CUSTOM_ID}: ${id}`, + } + ); + return savedObjects[0]; +}; + +const updateMonitor = async ( + savedObjectsClient: SavedObjectsClientContract, + encryptedSavedObjectsClient: EncryptedSavedObjectsClient, + previousMonitor: SavedObjectsFindResult, + normalizedMonitor: BrowserFields, + server: UptimeServerSetup +): Promise<{ + editedMonitor: SavedObjectsUpdateResponse; + errors: ServiceLocationErrors; +}> => { + const decryptedPreviousMonitor = + await encryptedSavedObjectsClient.getDecryptedAsInternalUser( + syntheticsMonitor.name, + previousMonitor.id, + { + namespace: previousMonitor.namespaces?.[0], + } + ); + const { + attributes: { [ConfigKey.REVISION]: _, ...normalizedPreviousMonitorAttributes }, + } = normalizeSecrets(decryptedPreviousMonitor); + const hasMonitorBeenEdited = !isEqual(normalizedMonitor, normalizedPreviousMonitorAttributes); + const monitorWithRevision = formatSecrets({ + ...normalizedMonitor, + revision: hasMonitorBeenEdited + ? (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1 + : previousMonitor.attributes[ConfigKey.REVISION], + }); + const editedMonitor: SavedObjectsUpdateResponse = + await savedObjectsClient.update(syntheticsMonitorType, previousMonitor.id, { + ...monitorWithRevision, + urls: '', + }); + + if (hasMonitorBeenEdited) { + syncEditedMonitor({ + editedMonitor: normalizedMonitor, + editedMonitorSavedObject: editedMonitor, + previousMonitor, + server, + }); + } + + return { editedMonitor, errors: [] }; +}; + +const configurePushMonitors = async ({ + savedObjectsClient, + encryptedSavedObjectsClient, + locations, + monitor, + createdMonitors, + updatedMonitors, + failedMonitors, + server, +}: { + savedObjectsClient: SavedObjectsClientContract; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + locations: Locations; + monitor: PushBrowserMonitor; + createdMonitors: string[]; + updatedMonitors: string[]; + failedMonitors: string[]; + server: UptimeServerSetup; +}) => { + try { + // check to see if monitor already exists + const normalizedMonitor = normalizePushedMonitor({ locations, monitor }); + const previousMonitor = await getExistingMonitor(savedObjectsClient, monitor.id); + + if (previousMonitor) { + await updateMonitor( + savedObjectsClient, + encryptedSavedObjectsClient, + previousMonitor, + normalizedMonitor, + server + ); + updatedMonitors.push(monitor.id); + } else { + const newMonitor = await savedObjectsClient.create( + syntheticsMonitorType, + formatSecrets({ + ...normalizedMonitor, + revision: 1, + }) + ); + await syncNewMonitor({ server, monitor: normalizedMonitor, monitorSavedObject: newMonitor }); + createdMonitors.push(monitor.id); + } + } catch (e) { + server.logger.error(e); + // determine failed monitors reason + failedMonitors.push(monitor.id); + // throw e; + } +}; diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/get_monitor.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/get_monitor.ts index 7018d50d82821..0be885c1c8f37 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/get_monitor.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/get_monitor.ts @@ -55,10 +55,11 @@ export const getAllSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ sortField: schema.maybe(schema.string()), sortOrder: schema.maybe(schema.oneOf([schema.literal('desc'), schema.literal('asc')])), search: schema.maybe(schema.string()), + query: schema.maybe(schema.string()), }), }, handler: async ({ request, savedObjectsClient, server }): Promise => { - const { perPage = 50, page, sortField, sortOrder, search } = request.query; + const { perPage = 50, page, sortField, sortOrder, search, query } = request.query; // TODO: add query/filtering params const { saved_objects: monitors, @@ -70,7 +71,7 @@ export const getAllSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ page, sortField, sortOrder, - filter: search ? `${syntheticsMonitorType}.attributes.name: ${search}` : '', + filter: query || (search ? `${syntheticsMonitorType}.attributes.name: ${search}` : ''), }); return { ...rest, diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts new file mode 100644 index 0000000000000..2d8e4b9af8e6d --- /dev/null +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -0,0 +1,123 @@ +/* + * 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 uuid from 'uuid'; +import expect from '@kbn/expect'; +import { PushMonitorsRequest } from '@kbn/synthetics-plugin/common/runtime_types'; +import { API_URLS } from '@kbn/synthetics-plugin/common/constants'; +import { syntheticsMonitorType } from '@kbn/synthetics-plugin/server/lib/saved_objects/synthetics_monitor'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { getFixtureJson } from './helper/get_fixture_json'; + +export default function ({ getService }: FtrProviderContext) { + describe('[PUT] /api/uptime/service/monitors', () => { + const supertest = getService('supertest'); + + let pushMonitors: PushMonitorsRequest; + + const setUniqueIds = (request: PushMonitorsRequest) => { + return { + ...request, + monitors: request.monitors.map((monitor) => ({ ...monitor, id: uuid.v4() })), + }; + }; + + beforeEach(() => { + pushMonitors = setUniqueIds(getFixtureJson('push_browser_monitor')); + }); + + it('push monitors - returns a list of successfully created monitors', async () => { + const apiResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + expect(apiResponse.body).eql({ + createdMonitors: pushMonitors.monitors.map((monitor) => monitor.id), + failedMonitors: [], + updatedMonitors: [], + }); + }); + + it('push monitors - returns a list of successfully updated monitors', async () => { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + const apiResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + expect(apiResponse.body).eql({ + createdMonitors: [], + failedMonitors: [], + updatedMonitors: pushMonitors.monitors.map((monitor) => monitor.id), + }); + }); + + it('push monitors - does not increment monitor revision unless a change has been made', async () => { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + const updatedMonitorsResponse = await Promise.all( + pushMonitors.monitors.map((monitor) => { + return supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ query: `${syntheticsMonitorType}.attributes.custom_id: ${monitor.id}` }) + .set('kbn-xsrf', 'true') + .expect(200); + }) + ); + + updatedMonitorsResponse.forEach((response) => { + expect(response.body.monitors[0].attributes.revision).eql(1); + }); + }); + + it('push monitors - increments monitor revision when a change has been made', async () => { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + const editedMonitors = { + ...pushMonitors, + monitors: pushMonitors.monitors.map((monitor) => ({ + ...monitor, + content: 'changed content', + })), + }; + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(editedMonitors); + + const updatedMonitorsResponse = await Promise.all( + pushMonitors.monitors.map((monitor) => { + return supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ query: `${syntheticsMonitorType}.attributes.custom_id: ${monitor.id}` }) + .set('kbn-xsrf', 'true') + .expect(200); + }) + ); + + updatedMonitorsResponse.forEach((response) => { + expect(response.body.monitors[0].attributes.revision).eql(2); + }); + }); + }); +} diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json new file mode 100644 index 0000000000000..fa0ddab7d7161 --- /dev/null +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json @@ -0,0 +1,22 @@ +{ + "monitors": [{ + "id": "test-id", + "throttling": { + "upload": 10, + "download": 20, + "latency": 30 + }, + "schedule": "10m", + "tags": [ + "cookie-test", + "browser" + ], + "screenshots": "off", + "content": "test source", + "ignoreHTTPSErrors": true, + "locations": ["US Central"], + "name": "Test Browser push monitor", + "apmServiceName": "cart-service" + }] +} + \ No newline at end of file diff --git a/x-pack/test/api_integration/apis/uptime/rest/index.ts b/x-pack/test/api_integration/apis/uptime/rest/index.ts index 3bfe81534c330..9c4b8eb0ebd39 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/index.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/index.ts @@ -75,6 +75,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { describe('uptime CRUD routes', () => { loadTestFile(require.resolve('./get_monitor')); loadTestFile(require.resolve('./add_monitor')); + loadTestFile(require.resolve('./add_monitor_push')); loadTestFile(require.resolve('./edit_monitor')); loadTestFile(require.resolve('./delete_monitor')); loadTestFile(require.resolve('./synthetics_enablement')); From 7673e5721d2adcdfba8422064c42e6bbc4e6b209 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 2 May 2022 13:05:01 -0400 Subject: [PATCH 10/68] adjust formatters and normalizers --- .../public/components/fleet_package/browser/formatters.ts | 2 ++ .../public/components/fleet_package/browser/normalizers.ts | 2 ++ .../public/components/fleet_package/common/formatters.ts | 1 + .../public/components/fleet_package/common/normalizers.ts | 1 + .../server/lib/synthetics_service/formatters/browser.ts | 2 ++ .../server/lib/synthetics_service/formatters/common.ts | 1 + 6 files changed, 9 insertions(+) diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/formatters.ts b/x-pack/plugins/synthetics/public/components/fleet_package/browser/formatters.ts index 374319d13d263..7f28ff1cf132b 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/formatters.ts +++ b/x-pack/plugins/synthetics/public/components/fleet_package/browser/formatters.ts @@ -45,6 +45,7 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.SOURCE_ZIP_PASSWORD]: null, [ConfigKey.SOURCE_ZIP_FOLDER]: null, [ConfigKey.SOURCE_ZIP_PROXY_URL]: null, + [ConfigKey.SOURCE_PUSH]: null, [ConfigKey.SOURCE_INLINE]: (fields) => stringToJsonFormatter(fields[ConfigKey.SOURCE_INLINE]), [ConfigKey.PARAMS]: null, [ConfigKey.SCREENSHOTS]: null, @@ -71,5 +72,6 @@ export const browserFormatters: BrowserFormatMap = { arrayToJsonFormatter(fields[ConfigKey.JOURNEY_FILTERS_TAGS]), [ConfigKey.THROTTLING_CONFIG]: throttlingFormatter, [ConfigKey.IGNORE_HTTPS_ERRORS]: null, + [ConfigKey.IS_PUSH_MONITOR]: null, ...commonFormatters, }; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/normalizers.ts b/x-pack/plugins/synthetics/public/components/fleet_package/browser/normalizers.ts index b33ae9e27bc7f..7866600687965 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/normalizers.ts +++ b/x-pack/plugins/synthetics/public/components/fleet_package/browser/normalizers.ts @@ -73,12 +73,14 @@ export const browserNormalizers: BrowserNormalizerMap = { [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_PUSH]: getBrowserNormalizer(ConfigKey.SOURCE_PUSH), [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.IS_PUSH_MONITOR]: getBrowserNormalizer(ConfigKey.IS_PUSH_MONITOR), [ConfigKey.DOWNLOAD_SPEED]: getThrottlingParamNormalizer(ConfigKey.DOWNLOAD_SPEED), [ConfigKey.UPLOAD_SPEED]: getThrottlingParamNormalizer(ConfigKey.UPLOAD_SPEED), [ConfigKey.LATENCY]: getThrottlingParamNormalizer(ConfigKey.LATENCY), diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/formatters.ts b/x-pack/plugins/synthetics/public/components/fleet_package/common/formatters.ts index a86894c3d7a48..8f02193573ac4 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/common/formatters.ts +++ b/x-pack/plugins/synthetics/public/components/fleet_package/common/formatters.ts @@ -14,6 +14,7 @@ export type CommonFormatMap = Record diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.ts b/x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.ts index 3cb312488868c..ef27371039835 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.ts +++ b/x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.ts @@ -62,6 +62,7 @@ export const getCommonCronToSecondsNormalizer = (key: ConfigKey) => { export const commonNormalizers: CommonNormalizerMap = { [ConfigKey.NAME]: (fields) => fields?.[ConfigKey.NAME]?.value ?? '', [ConfigKey.LOCATIONS]: getCommonNormalizer(ConfigKey.LOCATIONS), + [ConfigKey.CUSTOM_ID]: getCommonNormalizer(ConfigKey.CUSTOM_ID), [ConfigKey.ENABLED]: getCommonNormalizer(ConfigKey.ENABLED), [ConfigKey.MONITOR_TYPE]: getCommonNormalizer(ConfigKey.MONITOR_TYPE), [ConfigKey.LOCATIONS]: getCommonNormalizer(ConfigKey.LOCATIONS), diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts index 616d764c50abb..71557f1782a6e 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts @@ -21,6 +21,7 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.SOURCE_ZIP_PASSWORD]: null, [ConfigKey.SOURCE_ZIP_FOLDER]: null, [ConfigKey.SOURCE_ZIP_PROXY_URL]: null, + [ConfigKey.SOURCE_PUSH]: null, [ConfigKey.SOURCE_INLINE]: null, [ConfigKey.PARAMS]: null, [ConfigKey.SCREENSHOTS]: null, @@ -44,5 +45,6 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.JOURNEY_FILTERS_TAGS]: (fields) => arrayFormatter(fields[ConfigKey.JOURNEY_FILTERS_TAGS]), [ConfigKey.IGNORE_HTTPS_ERRORS]: null, + [ConfigKey.IS_PUSH_MONITOR]: null, ...commonFormatters, }; diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/common.ts index 9aee65e6fa14c..b308ad61a95b4 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/common.ts @@ -16,6 +16,7 @@ export type CommonFormatMap = Record; export const commonFormatters: CommonFormatMap = { [ConfigKey.NAME]: null, [ConfigKey.LOCATIONS]: null, + [ConfigKey.CUSTOM_ID]: null, [ConfigKey.ENABLED]: null, [ConfigKey.MONITOR_TYPE]: null, [ConfigKey.LOCATIONS]: null, From e4dbe4f1fd949610018a4a6ab8fd5c298a5d2314 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 2 May 2022 14:19:08 -0400 Subject: [PATCH 11/68] remove unused import --- x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts index e0c4e3b2fcdd5..36b7b253bd8f7 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts @@ -9,7 +9,6 @@ import expect from '@kbn/expect'; import { SimpleSavedObject } from '@kbn/core/public'; import { MonitorFields } from '@kbn/synthetics-plugin/common/runtime_types'; import { API_URLS } from '@kbn/synthetics-plugin/common/constants'; -import { formatSecrets } from '@kbn/synthetics-plugin/server/lib/synthetics_service/utils/secrets'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { getFixtureJson } from './helper/get_fixture_json'; From 8d6e8b0df090ca612e07bd8cfca433dee444ebf8 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 2 May 2022 14:21:42 -0400 Subject: [PATCH 12/68] remove log statement --- .../server/lib/synthetics_service/formatters/format_configs.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts index 5e07b37e07dc9..293ca64628e43 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts @@ -46,7 +46,6 @@ export const formatMonitorConfig = (configKeys: ConfigKey[], config: Partial Date: Fri, 6 May 2022 13:30:54 -0400 Subject: [PATCH 13/68] add push monitors route --- .../common/constants/monitor_defaults.ts | 3 +- .../common/constants/monitor_management.ts | 3 +- .../monitor_management/monitor_types.ts | 3 +- .../monitor_management/monitor_types_push.ts | 2 + .../fleet_package/common/formatters.ts | 2 +- .../fleet_package/common/normalizers.ts | 2 +- .../lib/saved_objects/synthetics_monitor.ts | 8 +- .../synthetics_service/formatters/common.ts | 1 - .../normalizers/browser.test.ts | 4 +- .../synthetics_service/normalizers/browser.ts | 5 +- .../synthetics_service/synthetics_service.ts | 2 +- .../synthetics_service/add_monitor_push.ts | 161 ++++++- .../synthetics_service/delete_monitor.ts | 84 ++-- .../monitor_validation.test.ts | 3 +- .../apis/uptime/rest/add_monitor_push.ts | 439 +++++++++++++++--- .../uptime/rest/fixtures/browser_monitor.json | 3 +- .../rest/fixtures/push_browser_monitor.json | 2 + 17 files changed, 595 insertions(+), 132 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts index 821ad31d68bbe..dff05123666d9 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -58,7 +58,8 @@ export const DEFAULT_BROWSER_ADVANCED_FIELDS: BrowserAdvancedFields = { export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { ...DEFAULT_COMMON_FIELDS, - [ConfigKey.CUSTOM_ID]: '', + [ConfigKey.JOURNEY_ID]: '', + [ConfigKey.PROJECT_ID]: '', [ConfigKey.IS_PUSH_MONITOR]: false, [ConfigKey.METADATA]: { script_source: { diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index 76ba2c6516392..9b7c706bf0539 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -25,7 +25,7 @@ export enum ConfigKey { PORT = 'url.port', PROXY_URL = 'proxy_url', PROXY_USE_LOCAL_RESOLVER = 'proxy_use_local_resolver', - CUSTOM_ID = 'custom_id', + JOURNEY_ID = 'journey_id', RESPONSE_BODY_CHECK_NEGATIVE = 'check.response.body.negative', RESPONSE_BODY_CHECK_POSITIVE = 'check.response.body.positive', RESPONSE_BODY_INDEX = 'response.include_body', @@ -47,6 +47,7 @@ export enum ConfigKey { SOURCE_ZIP_PASSWORD = 'source.zip_url.password', SOURCE_ZIP_FOLDER = 'source.zip_url.folder', SOURCE_ZIP_PROXY_URL = 'source.zip_url.proxy_url', + PROJECT_ID = 'project_id', SYNTHETICS_ARGS = 'synthetics_args', TLS_CERTIFICATE_AUTHORITIES = 'ssl.certificate_authorities', TLS_CERTIFICATE = 'ssl.certificate', diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index 0828ba144648d..6afd7e5bcabfd 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -74,7 +74,6 @@ export const CommonFieldsCodec = t.intersection([ [ConfigKey.LOCATIONS]: MonitorServiceLocationsCodec, }), t.partial({ - [ConfigKey.CUSTOM_ID]: t.string, [ConfigKey.TIMEOUT]: t.union([t.string, t.null]), [ConfigKey.REVISION]: t.number, }), @@ -203,6 +202,8 @@ export type ThrottlingConfigKey = t.TypeOf; export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ t.interface({ [ConfigKey.IS_PUSH_MONITOR]: t.boolean, + [ConfigKey.JOURNEY_ID]: t.string, + [ConfigKey.PROJECT_ID]: t.string, [ConfigKey.METADATA]: MetadataCodec, [ConfigKey.SOURCE_ZIP_URL]: t.string, [ConfigKey.SOURCE_ZIP_FOLDER]: t.string, diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts index 86a4d003d56f1..88acb6baf9016 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts @@ -27,6 +27,8 @@ export const PushBrowserMonitorCodec = t.intersection([ ]); export const PushMonitorsRequestCodec = t.interface({ + projectId: t.string, + keep_stale: t.boolean, monitors: t.array(PushBrowserMonitorCodec), }); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts index 8f02193573ac4..0d392630732a2 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts @@ -14,7 +14,7 @@ export type CommonFormatMap = Record diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts index 1c7689c9a2b6b..cb440d7109051 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts @@ -62,7 +62,7 @@ export const getCommonCronToSecondsNormalizer = (key: ConfigKey) => { export const commonNormalizers: CommonNormalizerMap = { [ConfigKey.NAME]: (fields) => fields?.[ConfigKey.NAME]?.value ?? '', [ConfigKey.LOCATIONS]: getCommonNormalizer(ConfigKey.LOCATIONS), - [ConfigKey.CUSTOM_ID]: getCommonNormalizer(ConfigKey.CUSTOM_ID), + [ConfigKey.JOURNEY_ID]: getCommonNormalizer(ConfigKey.JOURNEY_ID), [ConfigKey.ENABLED]: getCommonNormalizer(ConfigKey.ENABLED), [ConfigKey.MONITOR_TYPE]: getCommonNormalizer(ConfigKey.MONITOR_TYPE), [ConfigKey.LOCATIONS]: getCommonNormalizer(ConfigKey.LOCATIONS), diff --git a/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts b/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts index 7d1865ddc8bbc..d31caa03f7334 100644 --- a/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts +++ b/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts @@ -44,9 +44,15 @@ export const syntheticsMonitor: SavedObjectsType = { }, }, }, - custom_id: { + journey_id: { type: 'keyword', }, + project_id: { + type: 'keyword', + }, + is_push_monitor: { + type: 'boolean', + }, }, }, management: { diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/common.ts index b308ad61a95b4..9aee65e6fa14c 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/common.ts @@ -16,7 +16,6 @@ export type CommonFormatMap = Record; export const commonFormatters: CommonFormatMap = { [ConfigKey.NAME]: null, [ConfigKey.LOCATIONS]: null, - [ConfigKey.CUSTOM_ID]: null, [ConfigKey.ENABLED]: null, [ConfigKey.MONITOR_TYPE]: null, [ConfigKey.LOCATIONS]: null, diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts index 2803a64e0501d..de1cef1f23da9 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts @@ -72,7 +72,7 @@ describe('browser normalizers', () => { expect(actual).toEqual([ { ...DEFAULT_FIELDS[DataStream.BROWSER], - custom_id: 'test-id-1', + journey_id: 'test-id-1', ignore_https_errors: true, is_push_monitor: true, locations: [ @@ -105,7 +105,7 @@ describe('browser normalizers', () => { }, { ...DEFAULT_FIELDS[DataStream.BROWSER], - custom_id: 'test-id-2', + JOURNEY_ID: 'test-id-2', ignore_https_errors: false, is_push_monitor: true, locations: [ diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts index 114886fde91df..cb2c6217afd7a 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts @@ -48,9 +48,11 @@ type NormalizedPublicFields = Omit< export const normalizePushedMonitor = ({ locations = [], monitor, + projectId, }: { locations: Locations; monitor: PushBrowserMonitor; + projectId: string; }): BrowserFields => { const defaultFields = DEFAULT_FIELDS[DataStream.BROWSER]; const normalizedFields: NormalizedPublicFields = { @@ -61,7 +63,8 @@ export const normalizePushedMonitor = ({ number: `${new RegExp(/\d+/, 'g').exec(monitor.schedule)}` || '', unit: ScheduleUnit.MINUTES, }, - [ConfigKey.CUSTOM_ID]: monitor.id || defaultFields[ConfigKey.CUSTOM_ID], + [ConfigKey.PROJECT_ID]: projectId || defaultFields[ConfigKey.PROJECT_ID], + [ConfigKey.JOURNEY_ID]: monitor.id || defaultFields[ConfigKey.JOURNEY_ID], [ConfigKey.SOURCE_PUSH]: monitor.content || defaultFields[ConfigKey.SOURCE_PUSH], [ConfigKey.LOCATIONS]: monitor.locations ?.map((key) => { diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts index ebeee9c8937a6..7eee1f9c4eddb 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts @@ -397,7 +397,7 @@ export class SyntheticsService { return (monitors ?? []).map((monitor) => ({ ...normalizeSecrets(monitor).attributes, - id: monitor.attributes.custom_id || monitor.id, + id: monitor.attributes.JOURNEY_ID || monitor.id, fields_under_root: true, fields: { config_id: monitor.id }, })); diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts index 99640c6d63c99..df6455fffbcf4 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -35,24 +35,45 @@ import { formatSecrets, normalizeSecrets } from '../../lib/synthetics_service/ut import { UptimeServerSetup } from '../../lib/adapters/framework'; import { syncNewMonitor } from './add_monitor'; import { syncEditedMonitor } from './edit_monitor'; +import { deleteMonitor } from './delete_monitor'; + +interface StaleMonitor { + stale: boolean; + journeyId: string; + savedObjectId: string; +} +type StaleMonitorMap = Record; + +const getSuiteFilter = (projectId: string) => { + return `${syntheticsMonitorType}.attributes.${ConfigKey.IS_PUSH_MONITOR}: true AND ${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: ${projectId}`; +}; export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'PUT', path: API_URLS.SYNTHETICS_MONITORS_PUSH, validate: { - body: schema.any(), + body: schema.object({ + projectId: schema.string(), + keep_stale: schema.boolean(), + monitors: schema.arrayOf(schema.any()), + }), }, handler: async ({ request, response, savedObjectsClient, server }): Promise => { const monitors = (request.body?.monitors as PushBrowserMonitor[]) || []; + const { keep_stale: keepStale, projectId } = request.body || {}; const locations: Locations = (await getServiceLocations(server)).locations; const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); + const staleMonitorsMap = await getAllPushMonitorsForSuite(savedObjectsClient, projectId); const createdMonitors: string[] = []; + const deletedMonitors: string[] = []; const updatedMonitors: string[] = []; + const staleMonitors: string[] = []; const failedMonitors: string[] = []; + const failedStaleMonitors: string[] = []; await Promise.all( monitors.map((monitor) => - configurePushMonitors({ + configurePushMonitor({ savedObjectsClient, encryptedSavedObjectsClient, locations, @@ -61,15 +82,28 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS updatedMonitors, failedMonitors, server, + staleMonitorsMap, + projectId, }) ) ); + await handleStaleMonitors({ + savedObjectsClient, + staleMonitorsMap, + staleMonitors, + deletedMonitors, + server, + keepStale, + }); + return response.ok({ body: { createdMonitors, - failedMonitors, updatedMonitors, + staleMonitors, + deletedMonitors, + failedMonitors, }, }); }, @@ -77,18 +111,64 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS const getExistingMonitor = async ( savedObjectsClient: SavedObjectsClientContract, - id: string + journeyId: string, + projectId: string ): Promise> => { const { saved_objects: savedObjects } = await savedObjectsClient.find( { type: syntheticsMonitorType, perPage: 1, - filter: `${syntheticsMonitorType}.attributes.${ConfigKey.CUSTOM_ID}: ${id}`, + filter: `${getSuiteFilter(projectId)} AND ${syntheticsMonitorType}.attributes.${ + ConfigKey.JOURNEY_ID + }: ${journeyId}`, } ); return savedObjects[0]; }; +const getAllPushMonitorsForSuite = async ( + savedObjectsClient: SavedObjectsClientContract, + projectId: string +): Promise => { + const staleMonitors: StaleMonitorMap = {}; + let page = 1; + let totalMonitors = 0; + do { + const { total, saved_objects: savedObjects } = await getPushMonitorsForSuite( + savedObjectsClient, + page, + projectId + ); + savedObjects.forEach((savedObject) => { + const journeyId = (savedObject.attributes as BrowserFields)[ConfigKey.JOURNEY_ID]; + if (journeyId) { + staleMonitors[journeyId] = { + stale: true, + savedObjectId: savedObject.id, + journeyId, + }; + } + }); + + page++; + totalMonitors = total; + } while (Object.keys(staleMonitors).length < totalMonitors); + return staleMonitors; +}; + +const getPushMonitorsForSuite = async ( + savedObjectsClient: SavedObjectsClientContract, + page: number, + projectId: string +) => { + return await savedObjectsClient.find({ + type: syntheticsMonitorType, + page, + perPage: 1, + filter: getSuiteFilter(projectId), + }); +}; + const updateMonitor = async ( savedObjectsClient: SavedObjectsClientContract, encryptedSavedObjectsClient: EncryptedSavedObjectsClient, @@ -135,7 +215,7 @@ const updateMonitor = async ( return { editedMonitor, errors: [] }; }; -const configurePushMonitors = async ({ +const configurePushMonitor = async ({ savedObjectsClient, encryptedSavedObjectsClient, locations, @@ -144,6 +224,8 @@ const configurePushMonitors = async ({ updatedMonitors, failedMonitors, server, + staleMonitorsMap, + projectId, }: { savedObjectsClient: SavedObjectsClientContract; encryptedSavedObjectsClient: EncryptedSavedObjectsClient; @@ -153,11 +235,13 @@ const configurePushMonitors = async ({ updatedMonitors: string[]; failedMonitors: string[]; server: UptimeServerSetup; + staleMonitorsMap: StaleMonitorMap; + projectId: string; }) => { try { // check to see if monitor already exists - const normalizedMonitor = normalizePushedMonitor({ locations, monitor }); - const previousMonitor = await getExistingMonitor(savedObjectsClient, monitor.id); + const normalizedMonitor = normalizePushedMonitor({ locations, monitor, projectId }); + const previousMonitor = await getExistingMonitor(savedObjectsClient, monitor.id, projectId); if (previousMonitor) { await updateMonitor( @@ -168,6 +252,9 @@ const configurePushMonitors = async ({ server ); updatedMonitors.push(monitor.id); + if (staleMonitorsMap[monitor.id]) { + staleMonitorsMap[monitor.id].stale = false; + } } else { const newMonitor = await savedObjectsClient.create( syntheticsMonitorType, @@ -183,6 +270,62 @@ const configurePushMonitors = async ({ server.logger.error(e); // determine failed monitors reason failedMonitors.push(monitor.id); - // throw e; } }; + +const handleStaleMonitors = async ({ + savedObjectsClient, + server, + staleMonitorsMap, + staleMonitors, + deletedMonitors, + keepStale, +}: { + savedObjectsClient: SavedObjectsClientContract; + server: UptimeServerSetup; + staleMonitorsMap: StaleMonitorMap; + staleMonitors: string[]; + deletedMonitors: string[]; + keepStale: boolean; +}) => { + try { + const staleMonitorsData = Object.values(staleMonitorsMap).filter( + (monitor) => monitor.stale === true + ); + await Promise.all( + staleMonitorsData.map((monitor) => { + if (!keepStale) { + return deleteStaleMonitor({ + deletedMonitors, + savedObjectsClient, + server, + monitorId: monitor.savedObjectId, + journeyId: monitor.journeyId, + }); + } else { + staleMonitors.push(monitor.journeyId); + return null; + } + }) + ); + } catch (e) { + server.logger.error(e); + } +}; + +const deleteStaleMonitor = async ({ + deletedMonitors, + savedObjectsClient, + server, + monitorId, + journeyId, +}: { + deletedMonitors: string[]; + savedObjectsClient: SavedObjectsClientContract; + server: UptimeServerSetup; + monitorId: string; + journeyId: string; +}) => { + await deleteMonitor({ savedObjectsClient, server, monitorId }); + deletedMonitors.push(journeyId); +}; diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/delete_monitor.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/delete_monitor.ts index dc6fc759e81a4..083df7b1f240a 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/delete_monitor.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/delete_monitor.ts @@ -5,7 +5,7 @@ * 2.0. */ import { schema } from '@kbn/config-schema'; -import { SavedObjectsErrorHelpers } from '@kbn/core/server'; +import { SavedObjectsClientContract, SavedObjectsErrorHelpers } from '@kbn/core/server'; import { EncryptedSyntheticsMonitor, SyntheticsMonitorWithSecrets, @@ -22,6 +22,7 @@ import { formatTelemetryDeleteEvent, } from './telemetry/monitor_upgrade_sender'; import { normalizeSecrets } from '../../lib/synthetics_service/utils/secrets'; +import type { UptimeServerSetup } from '../../lib/adapters/framework'; export const deleteSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ method: 'DELETE', @@ -31,43 +32,11 @@ export const deleteSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ monitorId: schema.string({ minLength: 1, maxLength: 1024 }), }), }, - handler: async ({ - request, - response, - savedObjectsClient, - server: { encryptedSavedObjects, syntheticsService, logger, telemetry, kibanaVersion }, - }): Promise => { - const encryptedSavedObjectsClient = encryptedSavedObjects.getClient(); - + handler: async ({ request, response, savedObjectsClient, server }): Promise => { const { monitorId } = request.params; try { - const encryptedMonitor = await savedObjectsClient.get( - syntheticsMonitorType, - monitorId - ); - - const monitor = - await encryptedSavedObjectsClient.getDecryptedAsInternalUser( - syntheticsMonitor.name, - monitorId, - { - namespace: encryptedMonitor.namespaces?.[0], - } - ); - - const normalizedMonitor = normalizeSecrets(monitor); - - await savedObjectsClient.delete(syntheticsMonitorType, monitorId); - const errors = await syntheticsService.deleteConfigs([ - { ...normalizedMonitor.attributes, id: monitorId }, - ]); - - sendTelemetryEvents( - logger, - telemetry, - formatTelemetryDeleteEvent(monitor, kibanaVersion, new Date().toISOString(), errors) - ); + const errors = await deleteMonitor({ savedObjectsClient, server, monitorId }); if (errors && errors.length > 0) { return response.ok({ @@ -85,3 +54,48 @@ export const deleteSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ } }, }); + +export const deleteMonitor = async ({ + savedObjectsClient, + server, + monitorId, +}: { + savedObjectsClient: SavedObjectsClientContract; + server: UptimeServerSetup; + monitorId: string; +}) => { + const { syntheticsService, logger, telemetry, kibanaVersion, encryptedSavedObjects } = server; + const encryptedSavedObjectsClient = encryptedSavedObjects.getClient(); + try { + const encryptedMonitor = await savedObjectsClient.get( + syntheticsMonitorType, + monitorId + ); + + const monitor = + await encryptedSavedObjectsClient.getDecryptedAsInternalUser( + syntheticsMonitor.name, + monitorId, + { + namespace: encryptedMonitor.namespaces?.[0], + } + ); + + const normalizedMonitor = normalizeSecrets(monitor); + + await savedObjectsClient.delete(syntheticsMonitorType, monitorId); + const errors = await syntheticsService.deleteConfigs([ + { ...normalizedMonitor.attributes, id: monitorId }, + ]); + + sendTelemetryEvents( + logger, + telemetry, + formatTelemetryDeleteEvent(monitor, kibanaVersion, new Date().toISOString(), errors) + ); + + return errors; + } catch (e) { + throw e; + } +}; diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.test.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.test.ts index b29754649c960..ad3441641b774 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.test.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.test.ts @@ -161,7 +161,8 @@ describe('validateMonitor', () => { ...testZipUrlTLSFields, ...testCommonFields, [ConfigKey.IS_PUSH_MONITOR]: false, - [ConfigKey.CUSTOM_ID]: '', + [ConfigKey.JOURNEY_ID]: '', + [ConfigKey.PROJECT_ID]: '', [ConfigKey.METADATA]: testMetaData, [ConfigKey.SOURCE_INLINE]: '', [ConfigKey.SOURCE_PUSH]: '', diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts index 2d8e4b9af8e6d..10c4a8b38f659 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -15,6 +15,8 @@ import { getFixtureJson } from './helper/get_fixture_json'; export default function ({ getService }: FtrProviderContext) { describe('[PUT] /api/uptime/service/monitors', () => { const supertest = getService('supertest'); + const security = getService('security'); + const kibanaServer = getService('kibanaServer'); let pushMonitors: PushMonitorsRequest; @@ -25,99 +27,386 @@ export default function ({ getService }: FtrProviderContext) { }; }; + const deleteMonitor = async ( + journeyId: string, + projectId: string, + space: string = 'default', + username: string = '', + password: string = '' + ) => { + try { + const response = await supertest + .get(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}`) + .auth(username, password) + .query({ + query: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId} AND ${syntheticsMonitorType}.attributes.suite_id: ${projectId} `, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = response.body; + + if (monitors[0]?.id) { + await supertest + .delete(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}/${monitors[0].id}`) + .set('kbn-xsrf', 'true') + .send(pushMonitors) + .expect(200); + } + } catch (e) { + // eslint-disable-next-line no-console + console.error(e); + } + }; + beforeEach(() => { pushMonitors = setUniqueIds(getFixtureJson('push_browser_monitor')); }); it('push monitors - returns a list of successfully created monitors', async () => { - const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) - .set('kbn-xsrf', 'true') - .send(pushMonitors); - - expect(apiResponse.body).eql({ - createdMonitors: pushMonitors.monitors.map((monitor) => monitor.id), - failedMonitors: [], - updatedMonitors: [], - }); + try { + const apiResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + expect(apiResponse.body.updatedMonitors).eql([]); + expect(apiResponse.body.failedMonitors).eql([]); + expect(apiResponse.body.createdMonitors).eql( + pushMonitors.monitors.map((monitor) => monitor.id) + ); + } finally { + await Promise.all([ + pushMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.projectId); + }), + ]); + } }); it('push monitors - returns a list of successfully updated monitors', async () => { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) - .set('kbn-xsrf', 'true') - .send(pushMonitors); - - const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) - .set('kbn-xsrf', 'true') - .send(pushMonitors); - - expect(apiResponse.body).eql({ - createdMonitors: [], - failedMonitors: [], - updatedMonitors: pushMonitors.monitors.map((monitor) => monitor.id), - }); + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + const apiResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + expect(apiResponse.body.createdMonitors).eql([]); + expect(apiResponse.body.failedMonitors).eql([]); + expect(apiResponse.body.updatedMonitors).eql( + pushMonitors.monitors.map((monitor) => monitor.id) + ); + } finally { + await Promise.all([ + pushMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.projectId); + }), + ]); + } }); it('push monitors - does not increment monitor revision unless a change has been made', async () => { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) - .set('kbn-xsrf', 'true') - .send(pushMonitors); - - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) - .set('kbn-xsrf', 'true') - .send(pushMonitors); - - const updatedMonitorsResponse = await Promise.all( - pushMonitors.monitors.map((monitor) => { - return supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ query: `${syntheticsMonitorType}.attributes.custom_id: ${monitor.id}` }) - .set('kbn-xsrf', 'true') - .expect(200); - }) - ); + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); - updatedMonitorsResponse.forEach((response) => { - expect(response.body.monitors[0].attributes.revision).eql(1); - }); + const updatedMonitorsResponse = await Promise.all( + pushMonitors.monitors.map((monitor) => { + return supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ query: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) + .set('kbn-xsrf', 'true') + .expect(200); + }) + ); + + updatedMonitorsResponse.forEach((response) => { + expect(response.body.monitors[0].attributes.revision).eql(1); + }); + } finally { + await Promise.all([ + pushMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.projectId); + }), + ]); + } }); it('push monitors - increments monitor revision when a change has been made', async () => { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) - .set('kbn-xsrf', 'true') - .send(pushMonitors); - - const editedMonitors = { - ...pushMonitors, - monitors: pushMonitors.monitors.map((monitor) => ({ - ...monitor, - content: 'changed content', - })), - }; + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors); - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) - .set('kbn-xsrf', 'true') - .send(editedMonitors); + const editedMonitors = { + ...pushMonitors, + monitors: pushMonitors.monitors.map((monitor) => ({ + ...monitor, + content: 'changed content', + })), + }; - const updatedMonitorsResponse = await Promise.all( - pushMonitors.monitors.map((monitor) => { - return supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ query: `${syntheticsMonitorType}.attributes.custom_id: ${monitor.id}` }) - .set('kbn-xsrf', 'true') - .expect(200); - }) - ); + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(editedMonitors); + + const updatedMonitorsResponse = await Promise.all( + pushMonitors.monitors.map((monitor) => { + return supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ query: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) + .set('kbn-xsrf', 'true') + .expect(200); + }) + ); + + updatedMonitorsResponse.forEach((response) => { + expect(response.body.monitors[0].attributes.revision).eql(2); + }); + } finally { + await Promise.all([ + pushMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.projectId); + }), + ]); + } + }); + + it('push monitors - does not delete monitors when keep stale is true', async () => { + const secondMonitor = { ...pushMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [pushMonitors.monitors[0], secondMonitor]; + + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send({ + ...pushMonitors, + monitors: testMonitors, + }) + .expect(200); + + const apiResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send(pushMonitors) + .expect(200); + + // does not delete the stale monitor + const getResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + query: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const { monitors } = getResponse.body; + + expect(monitors.length).eql(1); + + expect(apiResponse.body.createdMonitors).eql([]); + expect(apiResponse.body.failedMonitors).eql([]); + expect(apiResponse.body.deletedMonitors).eql([]); + expect(apiResponse.body.updatedMonitors).eql([pushMonitors.monitors[0].id]); + expect(apiResponse.body.staleMonitors).eql([secondMonitor.id]); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.projectId); + }), + ]); + } + }); + + it('push monitors - deletes monitors when keep stale is false', async () => { + const secondMonitor = { ...pushMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [pushMonitors.monitors[0], secondMonitor]; + + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send({ + ...pushMonitors, + keep_stale: false, + monitors: testMonitors, + }) + .expect(200); + + const pushResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send({ ...pushMonitors, keep_stale: false }) + .expect(200); + + // expect monitor to have been deleted + const getResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + query: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const { monitors } = getResponse.body; + + expect(monitors[0]).eql(undefined); + + expect(pushResponse.body.createdMonitors).eql([]); + expect(pushResponse.body.failedMonitors).eql([]); + expect(pushResponse.body.updatedMonitors).eql([pushMonitors.monitors[0].id]); + expect(pushResponse.body.deletedMonitors).eql([secondMonitor.id]); + expect(pushResponse.body.staleMonitors).eql([]); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.projectId); + }), + ]); + } + }); + + it('push monitors - does not delete monitors from different suites when keep stale is false', async () => { + const secondMonitor = { ...pushMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [pushMonitors.monitors[0], secondMonitor]; + const testprojectId = 'test-suite-2'; + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send({ + ...pushMonitors, + keep_stale: false, + monitors: testMonitors, + }) + .expect(200); + + const pushResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send({ ...pushMonitors, keep_stale: false, projectId: testprojectId }) + .expect(200); + + // expect monitor not to have been deleted + const getResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + query: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const { monitors } = getResponse.body; + + expect(monitors.length).eql(1); + + expect(pushResponse.body.createdMonitors).eql([pushMonitors.monitors[0].id]); + expect(pushResponse.body.failedMonitors).eql([]); + expect(pushResponse.body.deletedMonitors).eql([]); + expect(pushResponse.body.updatedMonitors).eql([]); + expect(pushResponse.body.staleMonitors).eql([]); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.projectId); + }), + ]); + + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, testprojectId); + }), + ]); + } + }); - updatedMonitorsResponse.forEach((response) => { - expect(response.body.monitors[0].attributes.revision).eql(2); - }); + it('push monitors - does not delete a monitor from the same suite in a different space', async () => { + const secondMonitor = { ...pushMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [pushMonitors.monitors[0], secondMonitor]; + const username = 'admin'; + const roleName = `synthetics_admin`; + const password = `${username}-password`; + const SPACE_ID = `test-space-${uuid.v4()}`; + const SPACE_NAME = `test-space-name ${uuid.v4()}`; + await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send({ + ...pushMonitors, + keep_stale: false, + monitors: testMonitors, + }) + .expect(200); + const pushResponse = await supertest + .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PUSH}`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send({ ...pushMonitors, keep_stale: false }) + .expect(200); + // expect monitor not to have been deleted + const getResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .auth(username, password) + .query({ + query: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = getResponse.body; + expect(monitors.length).eql(1); + expect(pushResponse.body.createdMonitors).eql([pushMonitors.monitors[0].id]); + expect(pushResponse.body.failedMonitors).eql([]); + expect(pushResponse.body.deletedMonitors).eql([]); + expect(pushResponse.body.updatedMonitors).eql([]); + expect(pushResponse.body.staleMonitors).eql([]); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.projectId, 'default', username, password); + }), + ]); + await deleteMonitor( + secondMonitor.id, + pushMonitors.projectId, + SPACE_NAME, + username, + password + ); + await security.user.delete(username); + await security.role.delete(roleName); + } }); }); } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json index 280a733628c02..e786e62c2ca55 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json @@ -1,7 +1,8 @@ { "type": "browser", "enabled": true, - "custom_id": "", + "journey_id": "", + "project_id": "", "schedule": { "number": "3", "unit": "m" diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json index fa0ddab7d7161..3c5836c5f4f2b 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json @@ -1,4 +1,6 @@ { + "keep_stale": true, + "projectId": "test-suite", "monitors": [{ "id": "test-id", "throttling": { From ba5d12c7126cbe7fce96d423793b115977737329 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 9 May 2022 10:30:38 -0400 Subject: [PATCH 14/68] update tests --- .../test/api_integration/apis/uptime/rest/add_monitor_push.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts index 10c4a8b38f659..90da18074e931 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -39,7 +39,7 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}`) .auth(username, password) .query({ - query: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId} AND ${syntheticsMonitorType}.attributes.suite_id: ${projectId} `, + query: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId} AND ${syntheticsMonitorType}.attributes.project_id: ${projectId} `, }) .set('kbn-xsrf', 'true') .expect(200); From f6e3921c724693045ad6458c49210fc347d7ad9f Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 9 May 2022 11:49:30 -0400 Subject: [PATCH 15/68] add playwright options, filter match, and params --- .../common/constants/monitor_defaults.ts | 1 + .../common/constants/monitor_management.ts | 3 ++- .../monitor_management/monitor_types.ts | 1 + .../monitor_management/monitor_types_push.ts | 7 ++++- .../synthetics_service/formatters/browser.ts | 3 +++ .../synthetics_service/normalizers/browser.ts | 11 +++++--- .../synthetics_service/add_monitor_push.ts | 4 +-- .../apis/uptime/rest/add_monitor_push.ts | 26 +++++++------------ .../rest/fixtures/push_browser_monitor.json | 2 +- 9 files changed, 34 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts index dff05123666d9..96c6463d3cea3 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -60,6 +60,7 @@ export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { ...DEFAULT_COMMON_FIELDS, [ConfigKey.JOURNEY_ID]: '', [ConfigKey.PROJECT_ID]: '', + [ConfigKey.PLAYWRIGHT_OPTIONS]: '', [ConfigKey.IS_PUSH_MONITOR]: false, [ConfigKey.METADATA]: { script_source: { diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index 9b7c706bf0539..e594f67e8cd64 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -14,6 +14,7 @@ export enum ConfigKey { IS_PUSH_MONITOR = 'is_push_monitor', JOURNEY_FILTERS_MATCH = 'filter_journeys.match', JOURNEY_FILTERS_TAGS = 'filter_journeys.tags', + JOURNEY_ID = 'journey_id', MAX_REDIRECTS = 'max_redirects', METADATA = '__ui', MONITOR_TYPE = 'type', @@ -22,10 +23,10 @@ export enum ConfigKey { LOCATIONS = 'locations', PARAMS = 'params', PASSWORD = 'password', + PLAYWRIGHT_OPTIONS = 'playwright_options', PORT = 'url.port', PROXY_URL = 'proxy_url', PROXY_USE_LOCAL_RESOLVER = 'proxy_use_local_resolver', - JOURNEY_ID = 'journey_id', RESPONSE_BODY_CHECK_NEGATIVE = 'check.response.body.negative', RESPONSE_BODY_CHECK_POSITIVE = 'check.response.body.positive', RESPONSE_BODY_INDEX = 'response.include_body', diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index 6afd7e5bcabfd..d08af35e9ab1a 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -204,6 +204,7 @@ export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ [ConfigKey.IS_PUSH_MONITOR]: t.boolean, [ConfigKey.JOURNEY_ID]: t.string, [ConfigKey.PROJECT_ID]: t.string, + [ConfigKey.PLAYWRIGHT_OPTIONS]: t.string, [ConfigKey.METADATA]: MetadataCodec, [ConfigKey.SOURCE_ZIP_URL]: t.string, [ConfigKey.SOURCE_ZIP_FOLDER]: t.string, diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts index 88acb6baf9016..0564dbd4003f5 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts @@ -23,11 +23,16 @@ export const PushBrowserMonitorCodec = t.intersection([ tags: t.array(t.string), ignoreHTTPSErrors: t.boolean, apmServiceName: t.string, + playwrightOptions: t.record(t.string, t.unknown), + filter: t.interface({ + match: t.string, + }), + params: t.record(t.string, t.unknown), }), ]); export const PushMonitorsRequestCodec = t.interface({ - projectId: t.string, + project: t.string, keep_stale: t.boolean, monitors: t.array(PushBrowserMonitorCodec), }); diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts index 02d97e1942ee6..f6251d0e64ecb 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts @@ -56,5 +56,8 @@ export const browserFormatters: BrowserFormatMap = { arrayFormatter(fields[ConfigKey.JOURNEY_FILTERS_TAGS]), [ConfigKey.IGNORE_HTTPS_ERRORS]: null, [ConfigKey.IS_PUSH_MONITOR]: null, + [ConfigKey.JOURNEY_ID]: null, + [ConfigKey.PROJECT_ID]: null, + [ConfigKey.PLAYWRIGHT_OPTIONS]: null, ...commonFormatters, }; diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts index cb2c6217afd7a..fabb17ae43a21 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts @@ -35,9 +35,7 @@ type NormalizedPublicFields = Omit< | ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE | ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE | ConfigKey.ZIP_URL_TLS_VERSION - | ConfigKey.JOURNEY_FILTERS_MATCH | ConfigKey.JOURNEY_FILTERS_TAGS - | ConfigKey.PARAMS | ConfigKey.SYNTHETICS_ARGS | ConfigKey.PORT | ConfigKey.URLS @@ -91,6 +89,11 @@ export const normalizePushedMonitor = ({ monitor.ignoreHTTPSErrors || defaultFields[ConfigKey.IGNORE_HTTPS_ERRORS], [ConfigKey.SCREENSHOTS]: monitor.screenshots || defaultFields[ConfigKey.SCREENSHOTS], [ConfigKey.TAGS]: monitor.tags || defaultFields[ConfigKey.TAGS], + [ConfigKey.PLAYWRIGHT_OPTIONS]: + JSON.stringify(monitor.playwrightOptions) || defaultFields[ConfigKey.PLAYWRIGHT_OPTIONS], + [ConfigKey.PARAMS]: JSON.stringify(monitor.params) || defaultFields[ConfigKey.PARAMS], + [ConfigKey.JOURNEY_FILTERS_MATCH]: + monitor.filter?.match || defaultFields[ConfigKey.JOURNEY_FILTERS_MATCH], }; return { ...DEFAULT_FIELDS[DataStream.BROWSER], @@ -101,11 +104,13 @@ export const normalizePushedMonitor = ({ export const normalizePushedMonitors = ({ locations = [], monitors = [], + projectId, }: { locations: Locations; monitors: PushBrowserMonitor[]; + projectId: string; }) => { return monitors.map((monitor) => { - return normalizePushedMonitor({ monitor, locations }); + return normalizePushedMonitor({ monitor, locations, projectId }); }); }; diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts index df6455fffbcf4..c039d9d03f9f5 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -53,14 +53,14 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS path: API_URLS.SYNTHETICS_MONITORS_PUSH, validate: { body: schema.object({ - projectId: schema.string(), + project: schema.string(), keep_stale: schema.boolean(), monitors: schema.arrayOf(schema.any()), }), }, handler: async ({ request, response, savedObjectsClient, server }): Promise => { const monitors = (request.body?.monitors as PushBrowserMonitor[]) || []; - const { keep_stale: keepStale, projectId } = request.body || {}; + const { keep_stale: keepStale, project: projectId } = request.body || {}; const locations: Locations = (await getServiceLocations(server)).locations; const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); const staleMonitorsMap = await getAllPushMonitorsForSuite(savedObjectsClient, projectId); diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts index 90da18074e931..d61310dbcea3d 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -39,7 +39,7 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}`) .auth(username, password) .query({ - query: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId} AND ${syntheticsMonitorType}.attributes.project_id: ${projectId} `, + query: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId} AND ${syntheticsMonitorType}.attributes.project_id: ${projectId}`, }) .set('kbn-xsrf', 'true') .expect(200); @@ -77,7 +77,7 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.projectId); + return deleteMonitor(monitor.id, pushMonitors.project); }), ]); } @@ -103,7 +103,7 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.projectId); + return deleteMonitor(monitor.id, pushMonitors.project); }), ]); } @@ -137,7 +137,7 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.projectId); + return deleteMonitor(monitor.id, pushMonitors.project); }), ]); } @@ -179,7 +179,7 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.projectId); + return deleteMonitor(monitor.id, pushMonitors.project); }), ]); } @@ -226,7 +226,7 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.projectId); + return deleteMonitor(monitor.id, pushMonitors.project); }), ]); } @@ -274,7 +274,7 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.projectId); + return deleteMonitor(monitor.id, pushMonitors.project); }), ]); } @@ -322,7 +322,7 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.projectId); + return deleteMonitor(monitor.id, pushMonitors.project); }), ]); @@ -394,16 +394,10 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.projectId, 'default', username, password); + return deleteMonitor(monitor.id, pushMonitors.project, 'default', username, password); }), ]); - await deleteMonitor( - secondMonitor.id, - pushMonitors.projectId, - SPACE_NAME, - username, - password - ); + await deleteMonitor(secondMonitor.id, pushMonitors.project, SPACE_NAME, username, password); await security.user.delete(username); await security.role.delete(roleName); } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json index 3c5836c5f4f2b..fdb195a8e2521 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json @@ -1,6 +1,6 @@ { "keep_stale": true, - "projectId": "test-suite", + "project": "test-suite", "monitors": [{ "id": "test-id", "throttling": { From a4d311d563a0529fc02f0db718e29c057d85ca0b Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 9 May 2022 11:54:37 -0400 Subject: [PATCH 16/68] adjust tests --- .../test/api_integration/apis/uptime/rest/add_monitor_push.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts index d61310dbcea3d..7e2c693d80cfb 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -298,7 +298,7 @@ export default function ({ getService }: FtrProviderContext) { const pushResponse = await supertest .put(API_URLS.SYNTHETICS_MONITORS_PUSH) .set('kbn-xsrf', 'true') - .send({ ...pushMonitors, keep_stale: false, projectId: testprojectId }) + .send({ ...pushMonitors, keep_stale: false, project: testprojectId }) .expect(200); // expect monitor not to have been deleted From 2deb0d6c94408e7731881294860fe4305cb813be Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 9 May 2022 13:34:06 -0400 Subject: [PATCH 17/68] adjust tests --- .../monitor_management/monitor_types_push.ts | 2 +- .../normalizers/browser.test.ts | 89 +++++++++++++++++-- .../synthetics_service/normalizers/browser.ts | 15 ++-- 3 files changed, 92 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts index 0564dbd4003f5..2b3657219e495 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts @@ -15,7 +15,7 @@ export const PushMonitorThrottlingConfigCodec = t.interface({ }); export const PushBrowserMonitorCodec = t.intersection([ - t.interface({ id: t.string, name: t.string, schedule: t.string, content: t.string }), + t.interface({ id: t.string, name: t.string, schedule: t.number, content: t.string }), t.partial({ locations: t.array(t.string), throttling: PushMonitorThrottlingConfigCodec, diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts index de1cef1f23da9..73a8c56608089 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts @@ -16,6 +16,13 @@ import { normalizePushedMonitors } from './browser'; describe('browser normalizers', () => { describe('normalize push monitors', () => { + const playwrightOptions = { + headless: true, + }; + const params = { + url: 'test-url', + }; + const projectId = 'test-project-id'; const locations: Locations = [ { id: 'us_central', @@ -38,13 +45,13 @@ describe('browser normalizers', () => { screenshots: ScreenshotOption.OFF, name: 'test-name-1', content: 'test content 1', - schedule: '3m', + schedule: 3, throttling: { latency: 20, upload: 10, download: 5, }, - locations: ['US Central'], + locations: ['us_central'], tags: ['tag1', 'tag2'], ignoreHTTPSErrors: true, apmServiceName: 'cart-service', @@ -54,13 +61,33 @@ describe('browser normalizers', () => { screenshots: ScreenshotOption.ON, name: 'test-name-2', content: 'test content 2', - schedule: '10m', + schedule: 10, throttling: { latency: 18, upload: 15, download: 10, }, - locations: ['US Central', 'US East'], + params: {}, + playwrightOptions: {}, + locations: ['us_central', 'us_east'], + tags: ['tag3', 'tag4'], + ignoreHTTPSErrors: false, + apmServiceName: 'bean-service', + }, + { + id: 'test-id-3', + screenshots: ScreenshotOption.ON, + name: 'test-name-3', + content: 'test content 3', + schedule: 10, + throttling: { + latency: 18, + upload: 15, + download: 10, + }, + params, + playwrightOptions, + locations: ['us_central', 'us_east'], tags: ['tag3', 'tag4'], ignoreHTTPSErrors: false, apmServiceName: 'bean-service', @@ -68,7 +95,7 @@ describe('browser normalizers', () => { ]; it('properly normalizes browser monitor', () => { - const actual = normalizePushedMonitors({ locations, monitors }); + const actual = normalizePushedMonitors({ locations, monitors, projectId }); expect(actual).toEqual([ { ...DEFAULT_FIELDS[DataStream.BROWSER], @@ -101,11 +128,13 @@ describe('browser normalizers', () => { 'throttling.is_enabled': true, 'throttling.latency': '20', 'throttling.upload_speed': '10', + params: '', type: 'browser', + project_id: projectId, }, { ...DEFAULT_FIELDS[DataStream.BROWSER], - JOURNEY_ID: 'test-id-2', + journey_id: 'test-id-2', ignore_https_errors: false, is_push_monitor: true, locations: [ @@ -132,6 +161,7 @@ describe('browser normalizers', () => { ], name: 'test-name-2', params: '', + playwright_options: '', schedule: { number: '10', unit: 'm', @@ -146,6 +176,53 @@ describe('browser normalizers', () => { 'throttling.latency': '18', 'throttling.upload_speed': '15', type: 'browser', + project_id: projectId, + }, + { + ...DEFAULT_FIELDS[DataStream.BROWSER], + journey_id: 'test-id-3', + ignore_https_errors: false, + is_push_monitor: true, + locations: [ + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_central', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + }, + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_east', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + }, + ], + name: 'test-name-3', + params: JSON.stringify(params), + playwright_options: JSON.stringify(playwrightOptions), + schedule: { + number: '10', + unit: 'm', + }, + screenshots: 'on', + 'service.name': 'bean-service', + 'source.push.content': 'test content 3', + tags: ['tag3', 'tag4'], + 'throttling.config': '10d/15u/18l', + 'throttling.download_speed': '10', + 'throttling.is_enabled': true, + 'throttling.latency': '18', + 'throttling.upload_speed': '15', + type: 'browser', + project_id: projectId, }, ]); }); diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts index fabb17ae43a21..cc190787e5669 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.ts @@ -58,7 +58,7 @@ export const normalizePushedMonitor = ({ [ConfigKey.IS_PUSH_MONITOR]: true, [ConfigKey.NAME]: monitor.name || '', [ConfigKey.SCHEDULE]: { - number: `${new RegExp(/\d+/, 'g').exec(monitor.schedule)}` || '', + number: `${monitor.schedule}`, unit: ScheduleUnit.MINUTES, }, [ConfigKey.PROJECT_ID]: projectId || defaultFields[ConfigKey.PROJECT_ID], @@ -66,9 +66,7 @@ export const normalizePushedMonitor = ({ [ConfigKey.SOURCE_PUSH]: monitor.content || defaultFields[ConfigKey.SOURCE_PUSH], [ConfigKey.LOCATIONS]: monitor.locations ?.map((key) => { - return locations.find( - (location) => location.id.replace('_', ' ').toLowerCase() === key.toLowerCase() - ); + return locations.find((location) => location.id === key); }) .filter((location) => location !== undefined) as BrowserFields[ConfigKey.LOCATIONS], [ConfigKey.THROTTLING_CONFIG]: monitor.throttling @@ -89,9 +87,12 @@ export const normalizePushedMonitor = ({ monitor.ignoreHTTPSErrors || defaultFields[ConfigKey.IGNORE_HTTPS_ERRORS], [ConfigKey.SCREENSHOTS]: monitor.screenshots || defaultFields[ConfigKey.SCREENSHOTS], [ConfigKey.TAGS]: monitor.tags || defaultFields[ConfigKey.TAGS], - [ConfigKey.PLAYWRIGHT_OPTIONS]: - JSON.stringify(monitor.playwrightOptions) || defaultFields[ConfigKey.PLAYWRIGHT_OPTIONS], - [ConfigKey.PARAMS]: JSON.stringify(monitor.params) || defaultFields[ConfigKey.PARAMS], + [ConfigKey.PLAYWRIGHT_OPTIONS]: Object.keys(monitor.playwrightOptions || {}).length + ? JSON.stringify(monitor.playwrightOptions) + : defaultFields[ConfigKey.PLAYWRIGHT_OPTIONS], + [ConfigKey.PARAMS]: Object.keys(monitor.params || {}).length + ? JSON.stringify(monitor.params) + : defaultFields[ConfigKey.PARAMS], [ConfigKey.JOURNEY_FILTERS_MATCH]: monitor.filter?.match || defaultFields[ConfigKey.JOURNEY_FILTERS_MATCH], }; From 5c21e23b51becb2b51a51170c30f751d51051156 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 9 May 2022 13:38:38 -0400 Subject: [PATCH 18/68] adjust monitor type --- .../monitor_management/monitor_types.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index d08af35e9ab1a..e44cfff872d25 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -200,16 +200,20 @@ export const ThrottlingConfigKeyCodec = t.union([ export type ThrottlingConfigKey = t.TypeOf; export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ - t.interface({ - [ConfigKey.IS_PUSH_MONITOR]: t.boolean, - [ConfigKey.JOURNEY_ID]: t.string, - [ConfigKey.PROJECT_ID]: t.string, - [ConfigKey.PLAYWRIGHT_OPTIONS]: t.string, - [ConfigKey.METADATA]: MetadataCodec, - [ConfigKey.SOURCE_ZIP_URL]: t.string, - [ConfigKey.SOURCE_ZIP_FOLDER]: t.string, - [ConfigKey.SOURCE_ZIP_PROXY_URL]: t.string, - }), + t.union([ + t.interface({ + [ConfigKey.METADATA]: MetadataCodec, + [ConfigKey.SOURCE_ZIP_URL]: t.string, + [ConfigKey.SOURCE_ZIP_FOLDER]: t.string, + [ConfigKey.SOURCE_ZIP_PROXY_URL]: t.string, + }), + t.partial({ + [ConfigKey.PLAYWRIGHT_OPTIONS]: t.string, + [ConfigKey.JOURNEY_ID]: t.string, + [ConfigKey.PROJECT_ID]: t.string, + [ConfigKey.IS_PUSH_MONITOR]: t.boolean, + }), + ]), ZipUrlTLSFieldsCodec, ZipUrlTLSSensitiveFieldsCodec, CommonFieldsCodec, From 92b0746c673b346db34364fcfd880954a7f02804 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 9 May 2022 14:16:13 -0400 Subject: [PATCH 19/68] adjust types --- .../common/runtime_types/monitor_management/monitor_types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index e44cfff872d25..ee30f15da5d1a 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -200,7 +200,7 @@ export const ThrottlingConfigKeyCodec = t.union([ export type ThrottlingConfigKey = t.TypeOf; export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ - t.union([ + t.intersection([ t.interface({ [ConfigKey.METADATA]: MetadataCodec, [ConfigKey.SOURCE_ZIP_URL]: t.string, From 4b3e7cadd88a3ae7a6e35fff350b5857b08db448 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 10 May 2022 08:39:14 -0400 Subject: [PATCH 20/68] add validation and error message shape --- .../synthetics_service/add_monitor_push.ts | 51 ++++++++++++++++--- .../synthetics_service/monitor_validation.ts | 23 +++++++++ 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts index c039d9d03f9f5..9fdcd39cdecdd 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -36,6 +36,7 @@ import { UptimeServerSetup } from '../../lib/adapters/framework'; import { syncNewMonitor } from './add_monitor'; import { syncEditedMonitor } from './edit_monitor'; import { deleteMonitor } from './delete_monitor'; +import { validatePushMonitor } from './monitor_validation'; interface StaleMonitor { stale: boolean; @@ -43,6 +44,7 @@ interface StaleMonitor { savedObjectId: string; } type StaleMonitorMap = Record; +type FailedMonitors = Array<{ id: string; reason: string; details: string; payload?: object }>; const getSuiteFilter = (projectId: string) => { return `${syntheticsMonitorType}.attributes.${ConfigKey.IS_PUSH_MONITOR}: true AND ${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: ${projectId}`; @@ -68,8 +70,8 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS const deletedMonitors: string[] = []; const updatedMonitors: string[] = []; const staleMonitors: string[] = []; - const failedMonitors: string[] = []; - const failedStaleMonitors: string[] = []; + const failedMonitors: FailedMonitors = []; + const failedStaleMonitors: FailedMonitors = []; await Promise.all( monitors.map((monitor) => @@ -95,6 +97,7 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS deletedMonitors, server, keepStale, + failedStaleMonitors, }); return response.ok({ @@ -104,6 +107,7 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS staleMonitors, deletedMonitors, failedMonitors, + failedStaleMonitors, }, }); }, @@ -233,7 +237,7 @@ const configurePushMonitor = async ({ monitor: PushBrowserMonitor; createdMonitors: string[]; updatedMonitors: string[]; - failedMonitors: string[]; + failedMonitors: FailedMonitors; server: UptimeServerSetup; staleMonitorsMap: StaleMonitorMap; projectId: string; @@ -241,6 +245,23 @@ const configurePushMonitor = async ({ try { // check to see if monitor already exists const normalizedMonitor = normalizePushedMonitor({ locations, monitor, projectId }); + + const validationResult = validatePushMonitor(monitor); + + if (!validationResult.valid) { + const { reason: message, details, payload } = validationResult; + failedMonitors.push({ + id: monitor.id, + reason: message, + details, + payload, + }); + if (staleMonitorsMap[monitor.id]) { + staleMonitorsMap[monitor.id].stale = false; + } + return null; + } + const previousMonitor = await getExistingMonitor(savedObjectsClient, monitor.id, projectId); if (previousMonitor) { @@ -269,7 +290,12 @@ const configurePushMonitor = async ({ } catch (e) { server.logger.error(e); // determine failed monitors reason - failedMonitors.push(monitor.id); + failedMonitors.push({ + id: monitor.id, + reason: 'Failed to create or update monitor', + details: e.message, + payload: monitor, + }); } }; @@ -280,6 +306,7 @@ const handleStaleMonitors = async ({ staleMonitors, deletedMonitors, keepStale, + failedStaleMonitors, }: { savedObjectsClient: SavedObjectsClientContract; server: UptimeServerSetup; @@ -287,6 +314,7 @@ const handleStaleMonitors = async ({ staleMonitors: string[]; deletedMonitors: string[]; keepStale: boolean; + failedStaleMonitors: FailedMonitors; }) => { try { const staleMonitorsData = Object.values(staleMonitorsMap).filter( @@ -301,6 +329,7 @@ const handleStaleMonitors = async ({ server, monitorId: monitor.savedObjectId, journeyId: monitor.journeyId, + failedStaleMonitors, }); } else { staleMonitors.push(monitor.journeyId); @@ -319,13 +348,23 @@ const deleteStaleMonitor = async ({ server, monitorId, journeyId, + failedStaleMonitors, }: { deletedMonitors: string[]; + failedStaleMonitors: FailedMonitors; savedObjectsClient: SavedObjectsClientContract; server: UptimeServerSetup; monitorId: string; journeyId: string; }) => { - await deleteMonitor({ savedObjectsClient, server, monitorId }); - deletedMonitors.push(journeyId); + try { + await deleteMonitor({ savedObjectsClient, server, monitorId }); + deletedMonitors.push(journeyId); + } catch (e) { + failedStaleMonitors.push({ + id: monitorId, + reason: 'Failed to delete stale monitor', + details: e.message, + }); + } }; diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.ts index 446eaa5847319..d20d3c8360827 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.ts @@ -10,6 +10,8 @@ import { formatErrors } from '@kbn/securitysolution-io-ts-utils'; import { BrowserFieldsCodec, + PushBrowserMonitorCodec, + PushBrowserMonitor, ConfigKey, DataStream, DataStreamCodec, @@ -79,3 +81,24 @@ export function validateMonitor(monitorFields: MonitorFields): { return { valid: true, reason: '', details: '', payload: monitorFields }; } + +export function validatePushMonitor(monitorFields: PushBrowserMonitor): { + valid: boolean; + reason: string; + details: string; + payload: object; +} { + // Cast it to ICMPCodec to satisfy typing. During runtime, correct codec will be used to decode. + const decodedMonitor = PushBrowserMonitorCodec.decode(monitorFields); + + if (isLeft(decodedMonitor)) { + return { + valid: false, + reason: `Failed to save or update monitor. Configuration is not valid`, + details: formatErrors(decodedMonitor.left).join(' | '), + payload: monitorFields, + }; + } + + return { valid: true, reason: '', details: '', payload: monitorFields }; +} From 502649b57ed526bfcafab341c70015a0ca4b6896 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 10 May 2022 10:24:14 -0400 Subject: [PATCH 21/68] update fixture --- .../rest/fixtures/push_browser_monitor.json | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json index fdb195a8e2521..0c1a1d7d70419 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json @@ -1,24 +1,29 @@ { "keep_stale": true, "project": "test-suite", - "monitors": [{ - "id": "test-id", + "monitors": [ + { "throttling": { - "upload": 10, - "download": 20, - "latency": 30 + "download": 5, + "upload": 3, + "latency": 20 }, - "schedule": "10m", - "tags": [ - "cookie-test", - "browser" + "schedule": 10, + "locations": [ + "us-east4-a" ], - "screenshots": "off", - "content": "test source", - "ignoreHTTPSErrors": true, - "locations": ["US Central"], - "name": "Test Browser push monitor", - "apmServiceName": "cart-service" + "params": {}, + "playwrightOptions": { + "headless": true, + "chromiumSandbox": false + }, + "name": "check if title is present", + "id": "check if title is present", + "tags": [], + "content": "UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA", + "filter": { + "match": "check if title is present" + } }] } \ No newline at end of file From 0f3573d3b6a5d6d156110c4a9c07e827d111811c Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 10 May 2022 10:47:46 -0400 Subject: [PATCH 22/68] adjust types --- .../components/fleet_package/browser/formatters.ts | 3 +++ .../components/fleet_package/common/formatters.ts | 1 - .../apis/uptime/rest/fixtures/push_browser_monitor.json | 3 +-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts index 7f28ff1cf132b..51f230fd90820 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts @@ -73,5 +73,8 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.THROTTLING_CONFIG]: throttlingFormatter, [ConfigKey.IGNORE_HTTPS_ERRORS]: null, [ConfigKey.IS_PUSH_MONITOR]: null, + [ConfigKey.JOURNEY_ID]: null, + [ConfigKey.PROJECT_ID]: null, + [ConfigKey.PLAYWRIGHT_OPTIONS]: null, ...commonFormatters, }; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts index 0d392630732a2..a86894c3d7a48 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts @@ -14,7 +14,6 @@ export type CommonFormatMap = Record diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json index 0c1a1d7d70419..3fefdc24dabd3 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json @@ -1,8 +1,7 @@ { "keep_stale": true, "project": "test-suite", - "monitors": [ - { + "monitors": [{ "throttling": { "download": 5, "upload": 3, From 4a49b2c70db5d9bb13acda05e834e4fbc58d9d5f Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 10 May 2022 10:51:54 -0400 Subject: [PATCH 23/68] adjust normalizers --- .../components/fleet_package/browser/normalizers.ts | 3 +++ .../components/fleet_package/common/normalizers.ts | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) 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 index 7866600687965..cc07fe1e36d36 100644 --- 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 @@ -108,5 +108,8 @@ export const browserNormalizers: BrowserNormalizerMap = { ConfigKey.JOURNEY_FILTERS_TAGS ), [ConfigKey.IGNORE_HTTPS_ERRORS]: getBrowserNormalizer(ConfigKey.IGNORE_HTTPS_ERRORS), + [ConfigKey.JOURNEY_ID]: getBrowserNormalizer(ConfigKey.JOURNEY_ID), + [ConfigKey.PROJECT_ID]: getBrowserNormalizer(ConfigKey.PROJECT_ID), + [ConfigKey.PLAYWRIGHT_OPTIONS]: getBrowserNormalizer(ConfigKey.PLAYWRIGHT_OPTIONS), ...commonNormalizers, }; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts index cb440d7109051..0119b415faed8 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts @@ -62,7 +62,6 @@ export const getCommonCronToSecondsNormalizer = (key: ConfigKey) => { export const commonNormalizers: CommonNormalizerMap = { [ConfigKey.NAME]: (fields) => fields?.[ConfigKey.NAME]?.value ?? '', [ConfigKey.LOCATIONS]: getCommonNormalizer(ConfigKey.LOCATIONS), - [ConfigKey.JOURNEY_ID]: getCommonNormalizer(ConfigKey.JOURNEY_ID), [ConfigKey.ENABLED]: getCommonNormalizer(ConfigKey.ENABLED), [ConfigKey.MONITOR_TYPE]: getCommonNormalizer(ConfigKey.MONITOR_TYPE), [ConfigKey.LOCATIONS]: getCommonNormalizer(ConfigKey.LOCATIONS), From 04081f5cee604db119fcf14412b517149909396e Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 10 May 2022 13:38:55 -0400 Subject: [PATCH 24/68] Update x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts --- .../server/rest_api/synthetics_service/add_monitor_push.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts index 9fdcd39cdecdd..ed699a404cb74 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -289,7 +289,6 @@ const configurePushMonitor = async ({ } } catch (e) { server.logger.error(e); - // determine failed monitors reason failedMonitors.push({ id: monitor.id, reason: 'Failed to create or update monitor', From 7653ae0a85c2755a618c6088b4567df220f2f9be Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 10 May 2022 13:39:02 -0400 Subject: [PATCH 25/68] Update x-pack/plugins/synthetics/common/constants/rest_api.ts --- x-pack/plugins/synthetics/common/constants/rest_api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/common/constants/rest_api.ts b/x-pack/plugins/synthetics/common/constants/rest_api.ts index b024e0342b672..e5208e866e86b 100644 --- a/x-pack/plugins/synthetics/common/constants/rest_api.ts +++ b/x-pack/plugins/synthetics/common/constants/rest_api.ts @@ -45,6 +45,6 @@ export enum API_URLS { TRIGGER_MONITOR = '/internal/uptime/service/monitors/trigger', SERVICE_ALLOWED = '/internal/uptime/service/allowed', - // Service end points public + // Push monitor public endpoint SYNTHETICS_MONITORS_PUSH = '/api/synthetics/service/push/monitors', } From 38e82aa1cc1454af5f9f799b88c082504522e789 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 10 May 2022 15:46:33 -0400 Subject: [PATCH 26/68] quote queries --- .../rest_api/synthetics_service/add_monitor_push.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts index 9fdcd39cdecdd..26397a7acb155 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -47,7 +47,7 @@ type StaleMonitorMap = Record; type FailedMonitors = Array<{ id: string; reason: string; details: string; payload?: object }>; const getSuiteFilter = (projectId: string) => { - return `${syntheticsMonitorType}.attributes.${ConfigKey.IS_PUSH_MONITOR}: true AND ${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: ${projectId}`; + return `${syntheticsMonitorType}.attributes.${ConfigKey.IS_PUSH_MONITOR}: true AND ${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${projectId}"`; }; export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ @@ -118,13 +118,14 @@ const getExistingMonitor = async ( journeyId: string, projectId: string ): Promise> => { + const filter = `${getSuiteFilter(projectId)} AND ${syntheticsMonitorType}.attributes.${ + ConfigKey.JOURNEY_ID + }: "${journeyId}"`; const { saved_objects: savedObjects } = await savedObjectsClient.find( { type: syntheticsMonitorType, perPage: 1, - filter: `${getSuiteFilter(projectId)} AND ${syntheticsMonitorType}.attributes.${ - ConfigKey.JOURNEY_ID - }: ${journeyId}`, + filter, } ); return savedObjects[0]; From c13d5c0da3df0cc614e3c30aec304e6d31bbd3c3 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Thu, 12 May 2022 08:29:35 -0400 Subject: [PATCH 27/68] adjust source.pushed.content --- .../common/constants/monitor_management.ts | 2 +- .../formatters/format_configs.ts | 4 +++- .../synthetics_service/synthetics_service.ts | 18 ++++++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index e594f67e8cd64..5b210956ef899 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -41,7 +41,7 @@ export enum ConfigKey { REVISION = 'revision', SCHEDULE = 'schedule', SCREENSHOTS = 'screenshots', - SOURCE_PUSH = 'source.push.content', + SOURCE_PUSH = 'source.pushed.content', SOURCE_INLINE = 'source.inline.script', SOURCE_ZIP_URL = 'source.zip_url.url', SOURCE_ZIP_USERNAME = 'source.zip_url.username', diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts index 293ca64628e43..920b508c6acda 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/format_configs.ts @@ -10,6 +10,9 @@ import { ConfigKey, MonitorFields } from '../../../../common/runtime_types'; import { formatters } from '.'; const UI_KEYS_TO_SKIP = [ + ConfigKey.IS_PUSH_MONITOR, + ConfigKey.JOURNEY_ID, + ConfigKey.PROJECT_ID, ConfigKey.METADATA, ConfigKey.UPLOAD_SPEED, ConfigKey.DOWNLOAD_SPEED, @@ -17,7 +20,6 @@ const UI_KEYS_TO_SKIP = [ ConfigKey.IS_THROTTLING_ENABLED, ConfigKey.LOCATIONS, ConfigKey.REVISION, - ConfigKey.IS_PUSH_MONITOR, 'secrets', ]; diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts index 7eee1f9c4eddb..149471a1ee2c0 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/synthetics_service.ts @@ -395,12 +395,18 @@ export class SyntheticsService { }); } - return (monitors ?? []).map((monitor) => ({ - ...normalizeSecrets(monitor).attributes, - id: monitor.attributes.JOURNEY_ID || monitor.id, - fields_under_root: true, - fields: { config_id: monitor.id }, - })); + return (monitors ?? []).map((monitor) => { + const attributes = monitor.attributes as unknown as MonitorFields; + const pushBrowserMonitorId = attributes[ConfigKey.IS_PUSH_MONITOR] + ? `${attributes[ConfigKey.JOURNEY_ID]}-${attributes[ConfigKey.PROJECT_ID]}` + : undefined; + return { + ...normalizeSecrets(monitor).attributes, + id: pushBrowserMonitorId || monitor.id, + fields_under_root: true, + fields: { config_id: monitor.id }, + }; + }); } formatConfigs(configs: SyntheticsMonitorWithId[]) { From b984a29fd652fb921a55f191c447894f673789c1 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Sun, 15 May 2022 18:13:06 -0400 Subject: [PATCH 28/68] adjust test fixtures --- .../lib/synthetics_service/normalizers/browser.test.ts | 6 +++--- .../server/rest_api/synthetics_service/edit_monitor.ts | 2 +- .../apis/uptime/rest/fixtures/browser_monitor.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts index 73a8c56608089..04699d597fc64 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/normalizers/browser.test.ts @@ -121,7 +121,7 @@ describe('browser normalizers', () => { }, screenshots: 'off', 'service.name': 'cart-service', - 'source.push.content': 'test content 1', + 'source.pushed.content': 'test content 1', tags: ['tag1', 'tag2'], 'throttling.config': '5d/10u/20l', 'throttling.download_speed': '5', @@ -168,7 +168,7 @@ describe('browser normalizers', () => { }, screenshots: 'on', 'service.name': 'bean-service', - 'source.push.content': 'test content 2', + 'source.pushed.content': 'test content 2', tags: ['tag3', 'tag4'], 'throttling.config': '10d/15u/18l', 'throttling.download_speed': '10', @@ -214,7 +214,7 @@ describe('browser normalizers', () => { }, screenshots: 'on', 'service.name': 'bean-service', - 'source.push.content': 'test content 3', + 'source.pushed.content': 'test content 3', tags: ['tag3', 'tag4'], 'throttling.config': '10d/15u/18l', 'throttling.download_speed': '10', diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/edit_monitor.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/edit_monitor.ts index 1e73e71387074..16cfaf6d71c65 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/edit_monitor.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/edit_monitor.ts @@ -144,7 +144,7 @@ export const syncEditedMonitor = async ({ editedMonitorSavedObject, previousMonitor, server.kibanaVersion, - Boolean((monitor as MonitorFields)[ConfigKey.SOURCE_INLINE]), + Boolean((editedMonitor as MonitorFields)[ConfigKey.SOURCE_INLINE]), errors ) ); diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json index e786e62c2ca55..123c5c1241adc 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json @@ -27,7 +27,7 @@ "source.zip_url.folder": "", "source.zip_url.proxy_url": "", "source.inline.script": "step(\"Visit /users api route\", async () => {\\n const response = await page.goto('https://nextjs-test-synthetics.vercel.app/api/users');\\n expect(response.status()).toEqual(200);\\n});", - "source.push.content": "", + "source.pushed.content": "", "is_push_monitor": false, "params": "", "screenshots": "on", From 9c94decfccd8ee15e3b5fae34a0a1e408e87bcf0 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Sun, 15 May 2022 21:28:49 -0400 Subject: [PATCH 29/68] add journey and project id validation --- .../synthetics_service/add_monitor_push.ts | 2 +- .../synthetics_service/monitor_validation.ts | 24 ++- .../apis/uptime/rest/add_monitor_push.ts | 151 ++++++++++++++++++ 3 files changed, 175 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts index aa4727ba42c8c..7456d3a43fdff 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -247,7 +247,7 @@ const configurePushMonitor = async ({ // check to see if monitor already exists const normalizedMonitor = normalizePushedMonitor({ locations, monitor, projectId }); - const validationResult = validatePushMonitor(monitor); + const validationResult = validatePushMonitor(monitor, projectId); if (!validationResult.valid) { const { reason: message, details, payload } = validationResult; diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.ts index d20d3c8360827..d81a8ce48bd0b 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/monitor_validation.ts @@ -82,12 +82,34 @@ export function validateMonitor(monitorFields: MonitorFields): { return { valid: true, reason: '', details: '', payload: monitorFields }; } -export function validatePushMonitor(monitorFields: PushBrowserMonitor): { +export function validatePushMonitor( + monitorFields: PushBrowserMonitor, + projectId: string +): { valid: boolean; reason: string; details: string; payload: object; } { + const isValidId = new RegExp(/^[0-9A-Za-z-._~]+$/); + const isJourneyIdValid = isValidId.test(monitorFields.id); + const isProjectIdValid = isValidId.test(projectId); + const projectIdError = !isProjectIdValid + ? `Project id is invalid. Project id: ${projectId}. ` + : ''; + const journeyIdError = !isJourneyIdValid + ? `Journey id is invalid. Journey id: ${monitorFields.id}.` + : ''; + + if (!isProjectIdValid || !isJourneyIdValid) { + return { + valid: false, + reason: + 'Failed to save or update monitor. Journey id or Project id is not valid. Id must match pattern ^[0-9A-Za-z-._~]$', + details: `${projectIdError}${journeyIdError}`, + payload: monitorFields, + }; + } // Cast it to ICMPCodec to satisfy typing. During runtime, correct codec will be used to decode. const decodedMonitor = PushBrowserMonitorCodec.decode(monitorFields); diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts index 7e2c693d80cfb..9e304f3e80ab8 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -402,5 +402,156 @@ export default function ({ getService }: FtrProviderContext) { await security.role.delete(roleName); } }); + + it('push monitors - validates project id', async () => { + try { + const apiResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send({ ...pushMonitors, project: 'not a valid/ id$?' }); + + expect(apiResponse.body.updatedMonitors).eql([]); + expect(apiResponse.body.failedMonitors).eql([ + { + details: 'Project id is invalid. Project id: not a valid/ id$?. ', + id: pushMonitors.monitors[0].id, + payload: { + content: + 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', + filter: { + match: 'check if title is present', + }, + id: pushMonitors.monitors[0].id, + locations: ['us-east4-a'], + name: 'check if title is present', + params: {}, + playwrightOptions: { + chromiumSandbox: false, + headless: true, + }, + schedule: 10, + tags: [], + throttling: { + download: 5, + latency: 20, + upload: 3, + }, + }, + reason: + 'Failed to save or update monitor. Journey id or Project id is not valid. Id must match pattern ^[0-9A-Za-z-._~]$', + }, + ]); + expect(apiResponse.body.createdMonitors).eql([]); + } finally { + await Promise.all([ + pushMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.project); + }), + ]); + } + }); + + it('push monitors - validates journey id', async () => { + const id = 'not a valid/ id?&'; + try { + const apiResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send({ + ...pushMonitors, + monitors: [{ ...pushMonitors.monitors[0], id }], + }); + + expect(apiResponse.body.updatedMonitors).eql([]); + expect(apiResponse.body.failedMonitors).eql([ + { + details: `Journey id is invalid. Journey id: ${id}.`, + id, + payload: { + content: + 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', + filter: { + match: 'check if title is present', + }, + id, + locations: ['us-east4-a'], + name: 'check if title is present', + params: {}, + playwrightOptions: { + chromiumSandbox: false, + headless: true, + }, + schedule: 10, + tags: [], + throttling: { + download: 5, + latency: 20, + upload: 3, + }, + }, + reason: + 'Failed to save or update monitor. Journey id or Project id is not valid. Id must match pattern ^[0-9A-Za-z-._~]$', + }, + ]); + expect(apiResponse.body.createdMonitors).eql([]); + } finally { + await Promise.all([ + pushMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.project); + }), + ]); + } + }); + + it('push monitors - validates monitor type', async () => { + try { + const apiResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .set('kbn-xsrf', 'true') + .send({ + ...pushMonitors, + monitors: [{ ...pushMonitors.monitors[0], schedule: '3m', tags: '' }], + }); + + expect(apiResponse.body.updatedMonitors).eql([]); + expect(apiResponse.body.failedMonitors).eql([ + { + details: + 'Invalid value "3m" supplied to "schedule" | Invalid value "" supplied to "tags"', + id: pushMonitors.monitors[0].id, + payload: { + content: + 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', + filter: { + match: 'check if title is present', + }, + id: pushMonitors.monitors[0].id, + locations: ['us-east4-a'], + name: 'check if title is present', + params: {}, + playwrightOptions: { + chromiumSandbox: false, + headless: true, + }, + schedule: '3m', + tags: '', + throttling: { + download: 5, + latency: 20, + upload: 3, + }, + }, + reason: 'Failed to save or update monitor. Configuration is not valid', + }, + ]); + expect(apiResponse.body.createdMonitors).eql([]); + } finally { + await Promise.all([ + pushMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, pushMonitors.project); + }), + ]); + } + }); }); } From 98121339b2c3efcdac86e71a97fb789270a93214 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 16 May 2022 09:11:42 -0400 Subject: [PATCH 30/68] Update x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts Co-authored-by: Shahzad --- .../server/rest_api/synthetics_service/add_monitor_push.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts index 7456d3a43fdff..c2b72b7c2ca97 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -128,7 +128,7 @@ const getExistingMonitor = async ( filter, } ); - return savedObjects[0]; + return savedObjects?.[0]; }; const getAllPushMonitorsForSuite = async ( From 25e55d9eeb90923a9264f21c58c263fee296eb76 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 16 May 2022 09:21:25 -0400 Subject: [PATCH 31/68] Update x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts --- .../server/rest_api/synthetics_service/add_monitor_push.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts index c2b72b7c2ca97..a2055e2dad8ad 100644 --- a/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/rest_api/synthetics_service/add_monitor_push.ts @@ -169,7 +169,7 @@ const getPushMonitorsForSuite = async ( return await savedObjectsClient.find({ type: syntheticsMonitorType, page, - perPage: 1, + perPage: 500, filter: getSuiteFilter(projectId), }); }; From 1a50b8618805a1d4b127d606df83bbb9b90176fd Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 16 May 2022 10:28:24 -0400 Subject: [PATCH 32/68] adjust test fixture --- .../apis/uptime/rest/fixtures/push_browser_monitor.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json index 3fefdc24dabd3..e0618e749c2f6 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json @@ -17,7 +17,7 @@ "chromiumSandbox": false }, "name": "check if title is present", - "id": "check if title is present", + "id": "check-if-title-is-present", "tags": [], "content": "UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA", "filter": { From 8a80e65f8faef7a2ca9a1d169bf1fab93381dc03 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 16 May 2022 21:28:57 -0400 Subject: [PATCH 33/68] adjust import --- .../test/api_integration/apis/uptime/rest/add_monitor_push.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts index 9e304f3e80ab8..5dc058cefad95 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -8,7 +8,7 @@ import uuid from 'uuid'; import expect from '@kbn/expect'; import { PushMonitorsRequest } from '@kbn/synthetics-plugin/common/runtime_types'; import { API_URLS } from '@kbn/synthetics-plugin/common/constants'; -import { syntheticsMonitorType } from '@kbn/synthetics-plugin/server/lib/saved_objects/synthetics_monitor'; +import { syntheticsMonitorType } from '@kbn/synthetics-plugin/server/legacy_uptime/lib/saved_objects/synthetics_monitor'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { getFixtureJson } from './helper/get_fixture_json'; From 373ff731c7631c9e47e60f97e3e1a41123e68e57 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 17 May 2022 13:08:05 -0400 Subject: [PATCH 34/68] update push monitor api to use a class --- .../routes/monitor_cruds/add_monitor_push.ts | 349 +----------------- .../push_monitor_formatter.ts | 297 +++++++++++++++ .../apis/uptime/rest/add_monitor_push.ts | 13 +- 3 files changed, 320 insertions(+), 339 deletions(-) create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts index c7065df6e114c..7fcbe420bc1b2 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts @@ -4,51 +4,14 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { isEqual } from 'lodash'; import { schema } from '@kbn/config-schema'; -import { - SavedObjectsUpdateResponse, - SavedObjectsClientContract, - SavedObjectsFindResult, -} from '@kbn/core/server'; -import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; import { UMServerLibs } from '../../legacy_uptime/lib/lib'; -import { - BrowserFields, - ConfigKey, - MonitorFields, - SyntheticsMonitorWithSecrets, - EncryptedSyntheticsMonitor, - ServiceLocationErrors, - PushBrowserMonitor, - Locations, -} from '../../../common/runtime_types'; -import { - syntheticsMonitorType, - syntheticsMonitor, -} from '../../legacy_uptime/lib/saved_objects/synthetics_monitor'; +import { PushBrowserMonitor, Locations } from '../../../common/runtime_types'; + import { UMRestApiRouteFactory } from '../../legacy_uptime/routes/types'; import { API_URLS } from '../../../common/constants'; import { getServiceLocations } from '../../synthetics_service/get_service_locations'; -import { normalizePushedMonitor } from '../../synthetics_service/normalizers/browser'; -import { formatSecrets, normalizeSecrets } from '../../synthetics_service/utils/secrets'; -import { syncNewMonitor } from './add_monitor'; -import { syncEditedMonitor } from './edit_monitor'; -import { deleteMonitor } from './delete_monitor'; -import { validatePushMonitor } from './monitor_validation'; -import type { UptimeServerSetup } from '../../legacy_uptime/lib/adapters/framework'; - -interface StaleMonitor { - stale: boolean; - journeyId: string; - savedObjectId: string; -} -type StaleMonitorMap = Record; -type FailedMonitors = Array<{ id: string; reason: string; details: string; payload?: object }>; - -const getSuiteFilter = (projectId: string) => { - return `${syntheticsMonitorType}.attributes.${ConfigKey.IS_PUSH_MONITOR}: true AND ${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${projectId}"`; -}; +import { PushMonitorFormatter } from '../../synthetics_service/push_monitor_formatter'; export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'PUT', @@ -65,306 +28,28 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS const { keep_stale: keepStale, project: projectId } = request.body || {}; const locations: Locations = (await getServiceLocations(server)).locations; const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); - const staleMonitorsMap = await getAllPushMonitorsForSuite(savedObjectsClient, projectId); - const createdMonitors: string[] = []; - const deletedMonitors: string[] = []; - const updatedMonitors: string[] = []; - const staleMonitors: string[] = []; - const failedMonitors: FailedMonitors = []; - const failedStaleMonitors: FailedMonitors = []; - - await Promise.all( - monitors.map((monitor) => - configurePushMonitor({ - savedObjectsClient, - encryptedSavedObjectsClient, - locations, - monitor, - createdMonitors, - updatedMonitors, - failedMonitors, - server, - staleMonitorsMap, - projectId, - }) - ) - ); - await handleStaleMonitors({ + const pushMonitorFormatter = new PushMonitorFormatter({ + projectId, + keepStale, + locations, + encryptedSavedObjectsClient, savedObjectsClient, - staleMonitorsMap, - staleMonitors, - deletedMonitors, + monitors, server, - keepStale, - failedStaleMonitors, }); + await pushMonitorFormatter.configureAllPushMonitors(); + return response.ok({ body: { - createdMonitors, - updatedMonitors, - staleMonitors, - deletedMonitors, - failedMonitors, - failedStaleMonitors, + createdMonitors: pushMonitorFormatter.createdMonitors, + updatedMonitors: pushMonitorFormatter.updatedMonitors, + staleMonitors: pushMonitorFormatter.staleMonitors, + deletedMonitors: pushMonitorFormatter.deletedMonitors, + failedMonitors: pushMonitorFormatter.failedMonitors, + failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, }, }); }, }); - -const getExistingMonitor = async ( - savedObjectsClient: SavedObjectsClientContract, - journeyId: string, - projectId: string -): Promise> => { - const filter = `${getSuiteFilter(projectId)} AND ${syntheticsMonitorType}.attributes.${ - ConfigKey.JOURNEY_ID - }: "${journeyId}"`; - const { saved_objects: savedObjects } = await savedObjectsClient.find( - { - type: syntheticsMonitorType, - perPage: 1, - filter, - } - ); - return savedObjects?.[0]; -}; - -const getAllPushMonitorsForSuite = async ( - savedObjectsClient: SavedObjectsClientContract, - projectId: string -): Promise => { - const staleMonitors: StaleMonitorMap = {}; - let page = 1; - let totalMonitors = 0; - do { - const { total, saved_objects: savedObjects } = await getPushMonitorsForSuite( - savedObjectsClient, - page, - projectId - ); - savedObjects.forEach((savedObject) => { - const journeyId = (savedObject.attributes as BrowserFields)[ConfigKey.JOURNEY_ID]; - if (journeyId) { - staleMonitors[journeyId] = { - stale: true, - savedObjectId: savedObject.id, - journeyId, - }; - } - }); - - page++; - totalMonitors = total; - } while (Object.keys(staleMonitors).length < totalMonitors); - return staleMonitors; -}; - -const getPushMonitorsForSuite = async ( - savedObjectsClient: SavedObjectsClientContract, - page: number, - projectId: string -) => { - return await savedObjectsClient.find({ - type: syntheticsMonitorType, - page, - perPage: 500, - filter: getSuiteFilter(projectId), - }); -}; - -const updateMonitor = async ( - savedObjectsClient: SavedObjectsClientContract, - encryptedSavedObjectsClient: EncryptedSavedObjectsClient, - previousMonitor: SavedObjectsFindResult, - normalizedMonitor: BrowserFields, - server: UptimeServerSetup -): Promise<{ - editedMonitor: SavedObjectsUpdateResponse; - errors: ServiceLocationErrors; -}> => { - const decryptedPreviousMonitor = - await encryptedSavedObjectsClient.getDecryptedAsInternalUser( - syntheticsMonitor.name, - previousMonitor.id, - { - namespace: previousMonitor.namespaces?.[0], - } - ); - const { - attributes: { [ConfigKey.REVISION]: _, ...normalizedPreviousMonitorAttributes }, - } = normalizeSecrets(decryptedPreviousMonitor); - const hasMonitorBeenEdited = !isEqual(normalizedMonitor, normalizedPreviousMonitorAttributes); - const monitorWithRevision = formatSecrets({ - ...normalizedMonitor, - revision: hasMonitorBeenEdited - ? (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1 - : previousMonitor.attributes[ConfigKey.REVISION], - }); - const editedMonitor: SavedObjectsUpdateResponse = - await savedObjectsClient.update(syntheticsMonitorType, previousMonitor.id, { - ...monitorWithRevision, - urls: '', - }); - - if (hasMonitorBeenEdited) { - syncEditedMonitor({ - editedMonitor: normalizedMonitor, - editedMonitorSavedObject: editedMonitor, - previousMonitor, - server, - }); - } - - return { editedMonitor, errors: [] }; -}; - -const configurePushMonitor = async ({ - savedObjectsClient, - encryptedSavedObjectsClient, - locations, - monitor, - createdMonitors, - updatedMonitors, - failedMonitors, - server, - staleMonitorsMap, - projectId, -}: { - savedObjectsClient: SavedObjectsClientContract; - encryptedSavedObjectsClient: EncryptedSavedObjectsClient; - locations: Locations; - monitor: PushBrowserMonitor; - createdMonitors: string[]; - updatedMonitors: string[]; - failedMonitors: FailedMonitors; - server: UptimeServerSetup; - staleMonitorsMap: StaleMonitorMap; - projectId: string; -}) => { - try { - // check to see if monitor already exists - const normalizedMonitor = normalizePushedMonitor({ locations, monitor, projectId }); - - const validationResult = validatePushMonitor(monitor, projectId); - - if (!validationResult.valid) { - const { reason: message, details, payload } = validationResult; - failedMonitors.push({ - id: monitor.id, - reason: message, - details, - payload, - }); - if (staleMonitorsMap[monitor.id]) { - staleMonitorsMap[monitor.id].stale = false; - } - return null; - } - - const previousMonitor = await getExistingMonitor(savedObjectsClient, monitor.id, projectId); - - if (previousMonitor) { - await updateMonitor( - savedObjectsClient, - encryptedSavedObjectsClient, - previousMonitor, - normalizedMonitor, - server - ); - updatedMonitors.push(monitor.id); - if (staleMonitorsMap[monitor.id]) { - staleMonitorsMap[monitor.id].stale = false; - } - } else { - const newMonitor = await savedObjectsClient.create( - syntheticsMonitorType, - formatSecrets({ - ...normalizedMonitor, - revision: 1, - }) - ); - await syncNewMonitor({ server, monitor: normalizedMonitor, monitorSavedObject: newMonitor }); - createdMonitors.push(monitor.id); - } - } catch (e) { - server.logger.error(e); - failedMonitors.push({ - id: monitor.id, - reason: 'Failed to create or update monitor', - details: e.message, - payload: monitor, - }); - } -}; - -const handleStaleMonitors = async ({ - savedObjectsClient, - server, - staleMonitorsMap, - staleMonitors, - deletedMonitors, - keepStale, - failedStaleMonitors, -}: { - savedObjectsClient: SavedObjectsClientContract; - server: UptimeServerSetup; - staleMonitorsMap: StaleMonitorMap; - staleMonitors: string[]; - deletedMonitors: string[]; - keepStale: boolean; - failedStaleMonitors: FailedMonitors; -}) => { - try { - const staleMonitorsData = Object.values(staleMonitorsMap).filter( - (monitor) => monitor.stale === true - ); - await Promise.all( - staleMonitorsData.map((monitor) => { - if (!keepStale) { - return deleteStaleMonitor({ - deletedMonitors, - savedObjectsClient, - server, - monitorId: monitor.savedObjectId, - journeyId: monitor.journeyId, - failedStaleMonitors, - }); - } else { - staleMonitors.push(monitor.journeyId); - return null; - } - }) - ); - } catch (e) { - server.logger.error(e); - } -}; - -const deleteStaleMonitor = async ({ - deletedMonitors, - savedObjectsClient, - server, - monitorId, - journeyId, - failedStaleMonitors, -}: { - deletedMonitors: string[]; - failedStaleMonitors: FailedMonitors; - savedObjectsClient: SavedObjectsClientContract; - server: UptimeServerSetup; - monitorId: string; - journeyId: string; -}) => { - try { - await deleteMonitor({ savedObjectsClient, server, monitorId }); - deletedMonitors.push(journeyId); - } catch (e) { - failedStaleMonitors.push({ - id: monitorId, - reason: 'Failed to delete stale monitor', - details: e.message, - }); - } -}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts b/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts new file mode 100644 index 0000000000000..f2c8443eb6dc4 --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts @@ -0,0 +1,297 @@ +/* + * 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 { isEqual } from 'lodash'; +import { + SavedObjectsUpdateResponse, + SavedObjectsClientContract, + SavedObjectsFindResult, +} from '@kbn/core/server'; +import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; +import { + BrowserFields, + ConfigKey, + MonitorFields, + SyntheticsMonitorWithSecrets, + EncryptedSyntheticsMonitor, + ServiceLocationErrors, + PushBrowserMonitor, + Locations, +} from '../../common/runtime_types'; +import { + syntheticsMonitorType, + syntheticsMonitor, +} from '../legacy_uptime/lib/saved_objects/synthetics_monitor'; +import { normalizePushedMonitor } from './normalizers/browser'; +import { formatSecrets, normalizeSecrets } from './utils/secrets'; +import { syncNewMonitor } from '../routes/monitor_cruds/add_monitor'; +import { syncEditedMonitor } from '../routes/monitor_cruds/edit_monitor'; +import { deleteMonitor } from '../routes/monitor_cruds/delete_monitor'; +import { validatePushMonitor } from '../routes/monitor_cruds/monitor_validation'; +import type { UptimeServerSetup } from '../legacy_uptime/lib/adapters/framework'; + +interface StaleMonitor { + stale: boolean; + journeyId: string; + savedObjectId: string; +} +type StaleMonitorMap = Record; +type FailedMonitors = Array<{ id: string; reason: string; details: string; payload?: object }>; + +export class PushMonitorFormatter { + private projectId: string; + private keepStale: boolean; + private locations: Locations; + private savedObjectsClient: SavedObjectsClientContract; + private encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + private staleMonitorsMap: StaleMonitorMap = {}; + private monitors: PushBrowserMonitor[] = []; + public createdMonitors: string[] = []; + public deletedMonitors: string[] = []; + public updatedMonitors: string[] = []; + public staleMonitors: string[] = []; + public failedMonitors: FailedMonitors = []; + public failedStaleMonitors: FailedMonitors = []; + private server: UptimeServerSetup; + private projectFilter: string; + + constructor({ + locations, + keepStale, + savedObjectsClient, + encryptedSavedObjectsClient, + projectId, + monitors, + server, + }: { + locations: Locations; + keepStale: boolean; + savedObjectsClient: SavedObjectsClientContract; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + projectId: string; + monitors: PushBrowserMonitor[]; + server: UptimeServerSetup; + }) { + this.projectId = projectId; + this.locations = locations; + this.keepStale = keepStale; + this.savedObjectsClient = savedObjectsClient; + this.encryptedSavedObjectsClient = encryptedSavedObjectsClient; + this.monitors = monitors; + this.server = server; + this.projectFilter = `${syntheticsMonitorType}.attributes.${ConfigKey.IS_PUSH_MONITOR}: true AND ${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${this.projectId}"`; + } + + public configureAllPushMonitors = async () => { + this.staleMonitorsMap = await this.getAllPushMonitorsForProject(); + await Promise.all( + this.monitors.map((monitor) => + this.configurePushMonitor({ + monitor, + }) + ) + ); + + await this.handleStaleMonitors(); + }; + + private configurePushMonitor = async ({ monitor }: { monitor: PushBrowserMonitor }) => { + try { + // check to see if monitor already exists + const normalizedMonitor = normalizePushedMonitor({ + locations: this.locations, + monitor, + projectId: this.projectId, + }); + + const validationResult = validatePushMonitor(monitor, this.projectId); + + if (!validationResult.valid) { + const { reason: message, details, payload } = validationResult; + this.failedMonitors.push({ + id: monitor.id, + reason: message, + details, + payload, + }); + if (this.staleMonitorsMap[monitor.id]) { + this.staleMonitorsMap[monitor.id].stale = false; + } + return null; + } + + const previousMonitor = await this.getExistingMonitor(monitor.id); + + if (previousMonitor) { + await this.updateMonitor(previousMonitor, normalizedMonitor); + this.updatedMonitors.push(monitor.id); + if (this.staleMonitorsMap[monitor.id]) { + this.staleMonitorsMap[monitor.id].stale = false; + } + } else { + const newMonitor = await this.savedObjectsClient.create( + syntheticsMonitorType, + formatSecrets({ + ...normalizedMonitor, + revision: 1, + }) + ); + await syncNewMonitor({ + server: this.server, + monitor: normalizedMonitor, + monitorSavedObject: newMonitor, + }); + this.createdMonitors.push(monitor.id); + } + } catch (e) { + this.server.logger.error(e); + this.failedMonitors.push({ + id: monitor.id, + reason: 'Failed to create or update monitor', + details: e.message, + payload: monitor, + }); + } + }; + + private getAllPushMonitorsForProject = async (): Promise => { + const staleMonitors: StaleMonitorMap = {}; + let page = 1; + let totalMonitors = 0; + do { + const { total, saved_objects: savedObjects } = await this.getPushMonitorsForProject(page); + savedObjects.forEach((savedObject) => { + const journeyId = (savedObject.attributes as BrowserFields)[ConfigKey.JOURNEY_ID]; + if (journeyId) { + staleMonitors[journeyId] = { + stale: true, + savedObjectId: savedObject.id, + journeyId, + }; + } + }); + + page++; + totalMonitors = total; + } while (Object.keys(staleMonitors).length < totalMonitors); + return staleMonitors; + }; + + private getPushMonitorsForProject = async (page: number) => { + return await this.savedObjectsClient.find({ + type: syntheticsMonitorType, + page, + perPage: 500, + filter: this.projectFilter, + }); + }; + + private getExistingMonitor = async ( + journeyId: string + ): Promise> => { + const filter = `${this.projectFilter} AND ${syntheticsMonitorType}.attributes.${ConfigKey.JOURNEY_ID}: "${journeyId}"`; + const { saved_objects: savedObjects } = + await this.savedObjectsClient.find({ + type: syntheticsMonitorType, + perPage: 1, + filter, + }); + return savedObjects?.[0]; + }; + + private updateMonitor = async ( + previousMonitor: SavedObjectsFindResult, + normalizedMonitor: BrowserFields + ): Promise<{ + editedMonitor: SavedObjectsUpdateResponse; + errors: ServiceLocationErrors; + }> => { + const decryptedPreviousMonitor = + await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser( + syntheticsMonitor.name, + previousMonitor.id, + { + namespace: previousMonitor.namespaces?.[0], + } + ); + const { + attributes: { [ConfigKey.REVISION]: _, ...normalizedPreviousMonitorAttributes }, + } = normalizeSecrets(decryptedPreviousMonitor); + const hasMonitorBeenEdited = !isEqual(normalizedMonitor, normalizedPreviousMonitorAttributes); + const monitorWithRevision = formatSecrets({ + ...normalizedMonitor, + revision: hasMonitorBeenEdited + ? (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1 + : previousMonitor.attributes[ConfigKey.REVISION], + }); + const editedMonitor: SavedObjectsUpdateResponse = + await this.savedObjectsClient.update( + syntheticsMonitorType, + previousMonitor.id, + { + ...monitorWithRevision, + urls: '', + } + ); + + if (hasMonitorBeenEdited) { + syncEditedMonitor({ + editedMonitor: normalizedMonitor, + editedMonitorSavedObject: editedMonitor, + previousMonitor, + server: this.server, + }); + } + + return { editedMonitor, errors: [] }; + }; + + private handleStaleMonitors = async () => { + try { + const staleMonitorsData = Object.values(this.staleMonitorsMap).filter( + (monitor) => monitor.stale === true + ); + await Promise.all( + staleMonitorsData.map((monitor) => { + if (!this.keepStale) { + return this.deleteStaleMonitor({ + monitorId: monitor.savedObjectId, + journeyId: monitor.journeyId, + }); + } else { + this.staleMonitors.push(monitor.journeyId); + return null; + } + }) + ); + } catch (e) { + this.server.logger.error(e); + } + }; + + private deleteStaleMonitor = async ({ + monitorId, + journeyId, + }: { + monitorId: string; + journeyId: string; + }) => { + try { + await deleteMonitor({ + savedObjectsClient: this.savedObjectsClient, + server: this.server, + monitorId, + }); + this.deletedMonitors.push(journeyId); + } catch (e) { + this.failedStaleMonitors.push({ + id: monitorId, + reason: 'Failed to delete stale monitor', + details: e.message, + }); + } + }; +} diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts index 5dc058cefad95..751127fd75179 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -39,12 +39,11 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}`) .auth(username, password) .query({ - query: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId} AND ${syntheticsMonitorType}.attributes.project_id: ${projectId}`, + query: `${syntheticsMonitorType}.attributes.journey_id: "${journeyId}" AND ${syntheticsMonitorType}.attributes.project_id: "${projectId}"`, }) .set('kbn-xsrf', 'true') .expect(200); const { monitors } = response.body; - if (monitors[0]?.id) { await supertest .delete(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}/${monitors[0].id}`) @@ -218,10 +217,10 @@ export default function ({ getService }: FtrProviderContext) { expect(monitors.length).eql(1); - expect(apiResponse.body.createdMonitors).eql([]); - expect(apiResponse.body.failedMonitors).eql([]); - expect(apiResponse.body.deletedMonitors).eql([]); - expect(apiResponse.body.updatedMonitors).eql([pushMonitors.monitors[0].id]); + // expect(apiResponse.body.createdMonitors).eql([]); + // expect(apiResponse.body.failedMonitors).eql([]); + // expect(apiResponse.body.deletedMonitors).eql([]); + // expect(apiResponse.body.updatedMonitors).eql([pushMonitors.monitors[0].id]); expect(apiResponse.body.staleMonitors).eql([secondMonitor.id]); } finally { await Promise.all([ @@ -397,7 +396,7 @@ export default function ({ getService }: FtrProviderContext) { return deleteMonitor(monitor.id, pushMonitors.project, 'default', username, password); }), ]); - await deleteMonitor(secondMonitor.id, pushMonitors.project, SPACE_NAME, username, password); + await deleteMonitor(pushMonitors.monitors[0].id, pushMonitors.project, username, password); await security.user.delete(username); await security.role.delete(roleName); } From f7775ae25c055f831b4887ab147332cba4cfcdab Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 17 May 2022 16:59:04 -0400 Subject: [PATCH 35/68] add namespace --- .../common/constants/monitor_management.ts | 2 + .../monitor_management/monitor_types.ts | 2 + x-pack/plugins/synthetics/kibana.json | 3 +- .../lib/adapters/framework/adapter_types.ts | 3 + x-pack/plugins/synthetics/server/plugin.ts | 1 + .../routes/monitor_cruds/add_monitor_push.ts | 2 + .../normalizers/browser.test.ts | 7 +- .../synthetics_service/normalizers/browser.ts | 10 +- .../push_monitor_formatter.ts | 5 + .../synthetics_service/synthetics_service.ts | 2 +- .../apis/uptime/rest/add_monitor_push.ts | 120 +++++++++++++++++- 11 files changed, 150 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index 5b210956ef899..e0ae968d583c2 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -8,6 +8,7 @@ // values must match keys in the integration package export enum ConfigKey { APM_SERVICE_NAME = 'service.name', + CUSTOM_HEARTBEAT_ID = 'custom_heartbeat_id', ENABLED = 'enabled', HOSTS = 'hosts', IGNORE_HTTPS_ERRORS = 'ignore_https_errors', @@ -24,6 +25,7 @@ export enum ConfigKey { PARAMS = 'params', PASSWORD = 'password', PLAYWRIGHT_OPTIONS = 'playwright_options', + ORIGINAL_SPACE = 'original_space', // the original space the montior was saved in. Used by push monitors to ensure uniqueness of monitor id sent to heartbeat and prevent data collisions PORT = 'url.port', PROXY_URL = 'proxy_url', PROXY_USE_LOCAL_RESOLVER = 'proxy_use_local_resolver', diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index ee30f15da5d1a..a26d54472ee8f 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -212,6 +212,8 @@ export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ [ConfigKey.JOURNEY_ID]: t.string, [ConfigKey.PROJECT_ID]: t.string, [ConfigKey.IS_PUSH_MONITOR]: t.boolean, + [ConfigKey.ORIGINAL_SPACE]: t.string, + [ConfigKey.CUSTOM_HEARTBEAT_ID]: t.string, }), ]), ZipUrlTLSFieldsCodec, diff --git a/x-pack/plugins/synthetics/kibana.json b/x-pack/plugins/synthetics/kibana.json index bb827019fc70a..9597d05a44229 100644 --- a/x-pack/plugins/synthetics/kibana.json +++ b/x-pack/plugins/synthetics/kibana.json @@ -20,7 +20,8 @@ "taskManager", "triggersActionsUi", "usageCollection", - "unifiedSearch" + "unifiedSearch", + "spaces" ], "server": true, "ui": true, diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/synthetics/server/legacy_uptime/lib/adapters/framework/adapter_types.ts index 1354681a2e938..34e8ff84535bf 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/lib/adapters/framework/adapter_types.ts @@ -27,6 +27,7 @@ import { MlPluginSetup as MlSetup } from '@kbn/ml-plugin/server'; import { RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/server'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; import { CloudSetup } from '@kbn/cloud-plugin/server'; +import { SpacesPluginSetup } from '@kbn/spaces-plugin/server'; import { FleetStartContract } from '@kbn/fleet-plugin/server'; import { UptimeESClient } from '../../lib'; import type { TelemetryEventsSender } from '../../telemetry/sender'; @@ -50,6 +51,7 @@ export interface UptimeServerSetup { router: UptimeRouter; config: UptimeConfig; cloud?: CloudSetup; + spaces: SpacesPluginSetup; fleet: FleetStartContract; security: SecurityPluginStart; savedObjectsClient?: SavedObjectsClientContract; @@ -71,6 +73,7 @@ export interface UptimeCorePluginsSetup { usageCollection: UsageCollectionSetup; ml: MlSetup; cloud?: CloudSetup; + spaces: SpacesPluginSetup; ruleRegistry: RuleRegistryPluginSetupContract; encryptedSavedObjects: EncryptedSavedObjectsPluginSetup; taskManager: TaskManagerSetupContract; diff --git a/x-pack/plugins/synthetics/server/plugin.ts b/x-pack/plugins/synthetics/server/plugin.ts index a1b934b2ebbff..52b7120845940 100644 --- a/x-pack/plugins/synthetics/server/plugin.ts +++ b/x-pack/plugins/synthetics/server/plugin.ts @@ -84,6 +84,7 @@ export class Plugin implements PluginType { logger: this.logger, telemetry: this.telemetryEventsSender, isDev: this.initContext.env.mode.dev, + spaces: plugins.spaces, } as UptimeServerSetup; if (this.server.config.service) { diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts index 7fcbe420bc1b2..2194d8f346231 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts @@ -25,12 +25,14 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS }, handler: async ({ request, response, savedObjectsClient, server }): Promise => { const monitors = (request.body?.monitors as PushBrowserMonitor[]) || []; + const spaceId = server.spaces.spacesService.getSpaceId(request); const { keep_stale: keepStale, project: projectId } = request.body || {}; const locations: Locations = (await getServiceLocations(server)).locations; const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); const pushMonitorFormatter = new PushMonitorFormatter({ projectId, + spaceId, keepStale, locations, encryptedSavedObjectsClient, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index 3458ba933f81a..7d2e15604d7be 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -95,7 +95,12 @@ describe('browser normalizers', () => { ]; it('properly normalizes browser monitor', () => { - const actual = normalizePushedMonitors({ locations, monitors, projectId }); + const actual = normalizePushedMonitors({ + locations, + monitors, + projectId, + namespace: 'test-space', + }); expect(actual).toEqual([ { ...DEFAULT_FIELDS[DataStream.BROWSER], diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index 7677a3af65a8b..df6041088aa1a 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -40,17 +40,18 @@ type NormalizedPublicFields = Omit< | ConfigKey.PORT | ConfigKey.URLS | ConfigKey.ENABLED // should we allow enabled? - | ConfigKey.NAMESPACE // should we allow namespace? >; export const normalizePushedMonitor = ({ locations = [], monitor, projectId, + namespace, }: { locations: Locations; monitor: PushBrowserMonitor; projectId: string; + namespace: string; }): BrowserFields => { const defaultFields = DEFAULT_FIELDS[DataStream.BROWSER]; const normalizedFields: NormalizedPublicFields = { @@ -95,6 +96,9 @@ export const normalizePushedMonitor = ({ : defaultFields[ConfigKey.PARAMS], [ConfigKey.JOURNEY_FILTERS_MATCH]: monitor.filter?.match || defaultFields[ConfigKey.JOURNEY_FILTERS_MATCH], + [ConfigKey.NAMESPACE]: namespace || defaultFields[ConfigKey.NAMESPACE], + [ConfigKey.ORIGINAL_SPACE]: namespace || defaultFields[ConfigKey.ORIGINAL_SPACE], + [ConfigKey.CUSTOM_HEARTBEAT_ID]: `${monitor.id}-${projectId}-${namespace}`, }; return { ...DEFAULT_FIELDS[DataStream.BROWSER], @@ -106,12 +110,14 @@ export const normalizePushedMonitors = ({ locations = [], monitors = [], projectId, + namespace, }: { locations: Locations; monitors: PushBrowserMonitor[]; projectId: string; + namespace: string; }) => { return monitors.map((monitor) => { - return normalizePushedMonitor({ monitor, locations, projectId }); + return normalizePushedMonitor({ monitor, locations, projectId, namespace }); }); }; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts b/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts index f2c8443eb6dc4..0c4c524c7a319 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts @@ -43,6 +43,7 @@ type FailedMonitors = Array<{ id: string; reason: string; details: string; paylo export class PushMonitorFormatter { private projectId: string; + private spaceId: string; private keepStale: boolean; private locations: Locations; private savedObjectsClient: SavedObjectsClientContract; @@ -64,6 +65,7 @@ export class PushMonitorFormatter { savedObjectsClient, encryptedSavedObjectsClient, projectId, + spaceId, monitors, server, }: { @@ -72,10 +74,12 @@ export class PushMonitorFormatter { savedObjectsClient: SavedObjectsClientContract; encryptedSavedObjectsClient: EncryptedSavedObjectsClient; projectId: string; + spaceId: string; monitors: PushBrowserMonitor[]; server: UptimeServerSetup; }) { this.projectId = projectId; + this.spaceId = spaceId; this.locations = locations; this.keepStale = keepStale; this.savedObjectsClient = savedObjectsClient; @@ -105,6 +109,7 @@ export class PushMonitorFormatter { locations: this.locations, monitor, projectId: this.projectId, + namespace: this.spaceId, }); const validationResult = validatePushMonitor(monitor, this.projectId); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts index 4d7150ac0ba1d..aab753def2223 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts @@ -401,7 +401,7 @@ export class SyntheticsService { return (monitors ?? []).map((monitor) => { const attributes = monitor.attributes as unknown as MonitorFields; const pushBrowserMonitorId = attributes[ConfigKey.IS_PUSH_MONITOR] - ? `${attributes[ConfigKey.JOURNEY_ID]}-${attributes[ConfigKey.PROJECT_ID]}` + ? attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] : undefined; return { ...normalizeSecrets(monitor).attributes, diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts index 751127fd75179..a6a7027b66bfc 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts @@ -6,7 +6,7 @@ */ import uuid from 'uuid'; import expect from '@kbn/expect'; -import { PushMonitorsRequest } from '@kbn/synthetics-plugin/common/runtime_types'; +import { ConfigKey, PushMonitorsRequest } from '@kbn/synthetics-plugin/common/runtime_types'; import { API_URLS } from '@kbn/synthetics-plugin/common/constants'; import { syntheticsMonitorType } from '@kbn/synthetics-plugin/server/legacy_uptime/lib/saved_objects/synthetics_monitor'; import { FtrProviderContext } from '../../../ftr_provider_context'; @@ -396,7 +396,13 @@ export default function ({ getService }: FtrProviderContext) { return deleteMonitor(monitor.id, pushMonitors.project, 'default', username, password); }), ]); - await deleteMonitor(pushMonitors.monitors[0].id, pushMonitors.project, username, password); + await deleteMonitor( + pushMonitors.monitors[0].id, + pushMonitors.project, + SPACE_ID, + username, + password + ); await security.user.delete(username); await security.role.delete(roleName); } @@ -552,5 +558,115 @@ export default function ({ getService }: FtrProviderContext) { ]); } }); + + it('push monitors - saves space as data stream namespace', async () => { + const username = 'admin'; + const roleName = `synthetics_admin`; + const password = `${username}-password`; + const SPACE_ID = `test-space-${uuid.v4()}`; + const SPACE_NAME = `test-space-name ${uuid.v4()}`; + await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + await supertest + .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PUSH}`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send(pushMonitors) + .expect(200); + // expect monitor not to have been deleted + const getResponse = await supertest + .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) + .auth(username, password) + .query({ + query: `${syntheticsMonitorType}.attributes.journey_id: ${pushMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = getResponse.body; + expect(monitors.length).eql(1); + expect(monitors[0].attributes[ConfigKey.NAMESPACE]).eql(SPACE_ID); + } finally { + await deleteMonitor( + pushMonitors.monitors[0].id, + pushMonitors.project, + SPACE_ID, + username, + password + ); + await security.user.delete(username); + await security.role.delete(roleName); + } + }); + + it('push monitors - formats custom id appropriately', async () => { + const username = 'admin'; + const roleName = `synthetics_admin`; + const password = `${username}-password`; + const SPACE_ID = `test-space-${uuid.v4()}`; + const SPACE_NAME = `test-space-name ${uuid.v4()}`; + await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + await supertest + .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PUSH}`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send(pushMonitors) + .expect(200); + // expect monitor not to have been deleted + const getResponse = await supertest + .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) + .auth(username, password) + .query({ + query: `${syntheticsMonitorType}.attributes.journey_id: ${pushMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = getResponse.body; + expect(monitors.length).eql(1); + expect(monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]).eql( + `${pushMonitors.monitors[0].id}-${pushMonitors.project}-${SPACE_ID}` + ); + } finally { + await deleteMonitor( + pushMonitors.monitors[0].id, + pushMonitors.project, + SPACE_ID, + username, + password + ); + await security.user.delete(username); + await security.role.delete(roleName); + } + }); }); } From eafcbab96e63b631d16491682c17413e28b5feb2 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 May 2022 08:04:52 -0400 Subject: [PATCH 36/68] adjust types and tests --- .../components/fleet_package/browser/formatters.ts | 2 ++ .../components/fleet_package/browser/normalizers.ts | 2 ++ .../server/synthetics_service/formatters/browser.ts | 2 ++ .../synthetics_service/normalizers/browser.test.ts | 9 +++++++++ 4 files changed, 15 insertions(+) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts index 51f230fd90820..8519148f52364 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts @@ -76,5 +76,7 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.JOURNEY_ID]: null, [ConfigKey.PROJECT_ID]: null, [ConfigKey.PLAYWRIGHT_OPTIONS]: null, + [ConfigKey.CUSTOM_HEARTBEAT_ID]: null, + [ConfigKey.ORIGINAL_SPACE]: null, ...commonFormatters, }; 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 index cc07fe1e36d36..06938fba3ecf2 100644 --- 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 @@ -111,5 +111,7 @@ export const browserNormalizers: BrowserNormalizerMap = { [ConfigKey.JOURNEY_ID]: getBrowserNormalizer(ConfigKey.JOURNEY_ID), [ConfigKey.PROJECT_ID]: getBrowserNormalizer(ConfigKey.PROJECT_ID), [ConfigKey.PLAYWRIGHT_OPTIONS]: getBrowserNormalizer(ConfigKey.PLAYWRIGHT_OPTIONS), + [ConfigKey.CUSTOM_HEARTBEAT_ID]: getBrowserNormalizer(ConfigKey.CUSTOM_HEARTBEAT_ID), + [ConfigKey.ORIGINAL_SPACE]: getBrowserNormalizer(ConfigKey.ORIGINAL_SPACE), ...commonNormalizers, }; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts index 8b5ee8b1bbfc0..0e7aee9cf0f46 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts @@ -59,5 +59,7 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.JOURNEY_ID]: null, [ConfigKey.PROJECT_ID]: null, [ConfigKey.PLAYWRIGHT_OPTIONS]: null, + [ConfigKey.CUSTOM_HEARTBEAT_ID]: null, + [ConfigKey.ORIGINAL_SPACE]: null, ...commonFormatters, }; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index 7d2e15604d7be..e6477fb0034aa 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -136,6 +136,9 @@ describe('browser normalizers', () => { params: '', type: 'browser', project_id: projectId, + namespace: 'test-space', + original_space: 'test-space', + custom_heartbeat_id: 'test-id-3-test-project-id-test-space', }, { ...DEFAULT_FIELDS[DataStream.BROWSER], @@ -182,6 +185,9 @@ describe('browser normalizers', () => { 'throttling.upload_speed': '15', type: 'browser', project_id: projectId, + namespace: 'test-space', + original_space: 'test-space', + custom_heartbeat_id: 'test-id-3-test-project-id-test-space', }, { ...DEFAULT_FIELDS[DataStream.BROWSER], @@ -228,6 +234,9 @@ describe('browser normalizers', () => { 'throttling.upload_speed': '15', type: 'browser', project_id: projectId, + namespace: 'test-space', + original_space: 'test-space', + custom_heartbeat_id: 'test-id-3-test-project-id-test-space', }, ]); }); From a9cbdf4777fb5298d3f960c791834aa5c72aff32 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 May 2022 09:48:26 -0400 Subject: [PATCH 37/68] update test now --- .../server/routes/synthetics_service/test_now_monitor.ts | 2 +- .../server/synthetics_service/synthetics_service.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts b/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts index c2c897d153849..ad54f2a60c307 100644 --- a/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts @@ -51,7 +51,7 @@ export const testNowMonitorRoute: UMRestApiRouteFactory = () => ({ const errors = await syntheticsService.triggerConfigs(request, [ { ...normalizeSecrets(monitorWithSecrets).attributes, - id: monitorId, + id: monitorWithSecrets[CUSTOM_HEARTBEAT_ID] || monitorId, fields_under_root: true, fields: { config_id: monitorId, test_run_id: testRunId }, }, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts index aab753def2223..6e6b6f83e6871 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts @@ -403,11 +403,12 @@ export class SyntheticsService { const pushBrowserMonitorId = attributes[ConfigKey.IS_PUSH_MONITOR] ? attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] : undefined; + const id = attributes[ConfigKey.IS_PUSH_MONITOR] ? pushBrowserMonitorId : monitor.id; return { ...normalizeSecrets(monitor).attributes, - id: pushBrowserMonitorId || monitor.id, + id, // heartbeat id fields_under_root: true, - fields: { config_id: monitor.id }, + fields: { config_id: monitor.id }, // monitor saved object id }; }); } From 74ff77614a48e6b098eca84b583691df952f6591 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 May 2022 10:15:43 -0400 Subject: [PATCH 38/68] adjust id --- .../server/synthetics_service/synthetics_service.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts index 6e6b6f83e6871..db83ff9d5cdda 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts @@ -400,10 +400,7 @@ export class SyntheticsService { return (monitors ?? []).map((monitor) => { const attributes = monitor.attributes as unknown as MonitorFields; - const pushBrowserMonitorId = attributes[ConfigKey.IS_PUSH_MONITOR] - ? attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] - : undefined; - const id = attributes[ConfigKey.IS_PUSH_MONITOR] ? pushBrowserMonitorId : monitor.id; + const id = attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] || monitor.id; return { ...normalizeSecrets(monitor).attributes, id, // heartbeat id From d2ce516c69b36b35e724f5ec668ba2f38ba1748f Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 May 2022 10:58:14 -0400 Subject: [PATCH 39/68] adjust browser timeout --- .../synthetics/server/synthetics_service/normalizers/browser.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index df6041088aa1a..39efbe21dce46 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -99,6 +99,7 @@ export const normalizePushedMonitor = ({ [ConfigKey.NAMESPACE]: namespace || defaultFields[ConfigKey.NAMESPACE], [ConfigKey.ORIGINAL_SPACE]: namespace || defaultFields[ConfigKey.ORIGINAL_SPACE], [ConfigKey.CUSTOM_HEARTBEAT_ID]: `${monitor.id}-${projectId}-${namespace}`, + [ConfigKey.TIMEOUT]: null, }; return { ...DEFAULT_FIELDS[DataStream.BROWSER], From c9fa14b32820f9bf0e6a61bbd6f59f6168ddb6a0 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 May 2022 10:59:17 -0400 Subject: [PATCH 40/68] adjust test now --- .../server/routes/synthetics_service/test_now_monitor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts b/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts index ad54f2a60c307..18b0320a79afd 100644 --- a/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts @@ -51,7 +51,7 @@ export const testNowMonitorRoute: UMRestApiRouteFactory = () => ({ const errors = await syntheticsService.triggerConfigs(request, [ { ...normalizeSecrets(monitorWithSecrets).attributes, - id: monitorWithSecrets[CUSTOM_HEARTBEAT_ID] || monitorId, + id: monitorWithSecrets[ConfigKey.CUSTOM_HEARTBEAT_ID] || monitorId, fields_under_root: true, fields: { config_id: monitorId, test_run_id: testRunId }, }, From 493ed2f1e134dbe2b5808860d02a255a51fda509 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 May 2022 12:39:23 -0400 Subject: [PATCH 41/68] adjust types --- .../server/routes/synthetics_service/test_now_monitor.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts b/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts index 18b0320a79afd..fe5c7d35fd3d9 100644 --- a/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts @@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema'; import { v4 as uuidv4 } from 'uuid'; import { ConfigKey, + MonitorFields, SyntheticsMonitor, SyntheticsMonitorWithSecrets, } from '../../../common/runtime_types'; @@ -41,6 +42,7 @@ export const testNowMonitorRoute: UMRestApiRouteFactory = () => ({ syntheticsMonitor.name, monitorId ); + const normalizedMonitor = normalizeSecrets(monitorWithSecrets); const { [ConfigKey.SCHEDULE]: schedule, [ConfigKey.LOCATIONS]: locations } = monitor.attributes; @@ -50,8 +52,10 @@ export const testNowMonitorRoute: UMRestApiRouteFactory = () => ({ const errors = await syntheticsService.triggerConfigs(request, [ { - ...normalizeSecrets(monitorWithSecrets).attributes, - id: monitorWithSecrets[ConfigKey.CUSTOM_HEARTBEAT_ID] || monitorId, + ...normalizedMonitor.attributes, + id: + (normalizedMonitor.attributes as MonitorFields)[ConfigKey.CUSTOM_HEARTBEAT_ID] || + monitorId, fields_under_root: true, fields: { config_id: monitorId, test_run_id: testRunId }, }, From b82e50f6fe1112c14e3213694fa5b2f7b1b26adc Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 May 2022 14:12:44 -0400 Subject: [PATCH 42/68] adjust id logic --- .../synthetics/server/routes/monitor_cruds/add_monitor.ts | 2 +- .../server/routes/monitor_cruds/delete_monitor.ts | 7 ++++++- .../synthetics/server/routes/monitor_cruds/edit_monitor.ts | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts index cb1014c4c7b07..12b9e8b437400 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts @@ -68,7 +68,7 @@ export const syncNewMonitor = async ({ }) => { const errors = await server.syntheticsService.addConfig({ ...monitor, - id: monitorSavedObject.id, + id: (monitor as MonitorFields)[ConfigKey.CUSTOM_HEARTBEAT_ID] || monitorSavedObject.id, fields: { config_id: monitorSavedObject.id, }, diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor.ts index 7879a830e91d4..43753101c56d4 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor.ts @@ -87,7 +87,12 @@ export const deleteMonitor = async ({ await savedObjectsClient.delete(syntheticsMonitorType, monitorId); const errors = await syntheticsService.deleteConfigs([ - { ...normalizedMonitor.attributes, id: monitorId }, + { + ...normalizedMonitor.attributes, + id: + (normalizedMonitor.attributes as MonitorFields)[ConfigKey.CUSTOM_HEARTBEAT_ID] || + monitorId, + }, ]); sendTelemetryEvents( diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts index e7f7451b90c49..391e310ea97f8 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts @@ -129,7 +129,9 @@ export const syncEditedMonitor = async ({ const errors = await server.syntheticsService.pushConfigs([ { ...editedMonitor, - id: editedMonitorSavedObject.id, + id: + (editedMonitor as MonitorFields)[ConfigKey.CUSTOM_HEARTBEAT_ID] || + editedMonitorSavedObject.id, fields: { config_id: editedMonitorSavedObject.id, }, From 2c9093c8c5018ca4eaeaa9b0ce5dc0746c1e269f Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 18 May 2022 14:18:24 -0400 Subject: [PATCH 43/68] add enabled key --- .../runtime_types/monitor_management/monitor_types_push.ts | 1 + .../synthetics/server/synthetics_service/normalizers/browser.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts index 2b3657219e495..52ce5ab0c187a 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts @@ -28,6 +28,7 @@ export const PushBrowserMonitorCodec = t.intersection([ match: t.string, }), params: t.record(t.string, t.unknown), + enabled: t.boolean, }), ]); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index 39efbe21dce46..3e39d0b0dfa8b 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -39,7 +39,6 @@ type NormalizedPublicFields = Omit< | ConfigKey.SYNTHETICS_ARGS | ConfigKey.PORT | ConfigKey.URLS - | ConfigKey.ENABLED // should we allow enabled? >; export const normalizePushedMonitor = ({ @@ -100,6 +99,7 @@ export const normalizePushedMonitor = ({ [ConfigKey.ORIGINAL_SPACE]: namespace || defaultFields[ConfigKey.ORIGINAL_SPACE], [ConfigKey.CUSTOM_HEARTBEAT_ID]: `${monitor.id}-${projectId}-${namespace}`, [ConfigKey.TIMEOUT]: null, + [ConfigKey.ENABLED]: monitor.enabled || defaultFields[ConfigKey.ENABLED], }; return { ...DEFAULT_FIELDS[DataStream.BROWSER], From b0712e3414d84d57a595e9a358280844bf347253 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Thu, 19 May 2022 09:02:07 -0400 Subject: [PATCH 44/68] rename variables --- .../synthetics/common/constants/rest_api.ts | 4 +- .../runtime_types/monitor_management/index.ts | 2 +- ...types_push.ts => monitor_types_project.ts} | 16 +- .../legacy_uptime/lib/telemetry/types.ts | 2 +- .../plugins/synthetics/server/routes/index.ts | 4 +- ...monitor_push.ts => add_monitor_project.ts} | 14 +- .../monitor_cruds/monitor_validation.ts | 10 +- .../telemetry/monitor_upgrade_sender.test.ts | 2 +- .../telemetry/monitor_upgrade_sender.ts | 4 +- .../normalizers/browser.test.ts | 8 +- .../synthetics_service/normalizers/browser.ts | 12 +- ...matter.ts => project_monitor_formatter.ts} | 30 +- ...monitor_push.ts => add_monitor_project.ts} | 258 +++++++++--------- ...itor.json => project_browser_monitor.json} | 0 .../api_integration/apis/uptime/rest/index.ts | 2 +- 15 files changed, 187 insertions(+), 181 deletions(-) rename x-pack/plugins/synthetics/common/runtime_types/monitor_management/{monitor_types_push.ts => monitor_types_project.ts} (62%) rename x-pack/plugins/synthetics/server/routes/monitor_cruds/{add_monitor_push.ts => add_monitor_project.ts} (77%) rename x-pack/plugins/synthetics/server/synthetics_service/{push_monitor_formatter.ts => project_monitor_formatter.ts} (90%) rename x-pack/test/api_integration/apis/uptime/rest/{add_monitor_push.ts => add_monitor_project.ts} (69%) rename x-pack/test/api_integration/apis/uptime/rest/fixtures/{push_browser_monitor.json => project_browser_monitor.json} (100%) diff --git a/x-pack/plugins/synthetics/common/constants/rest_api.ts b/x-pack/plugins/synthetics/common/constants/rest_api.ts index e5208e866e86b..7400938e3a7cc 100644 --- a/x-pack/plugins/synthetics/common/constants/rest_api.ts +++ b/x-pack/plugins/synthetics/common/constants/rest_api.ts @@ -45,6 +45,6 @@ export enum API_URLS { TRIGGER_MONITOR = '/internal/uptime/service/monitors/trigger', SERVICE_ALLOWED = '/internal/uptime/service/allowed', - // Push monitor public endpoint - SYNTHETICS_MONITORS_PUSH = '/api/synthetics/service/push/monitors', + // Project monitor public endpoint + SYNTHETICS_MONITORS_PROJECT = '/api/synthetics/service/project/monitors', } diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/index.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/index.ts index 70eebae261743..73355d3144eac 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/index.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/index.ts @@ -10,5 +10,5 @@ export * from './config_key'; export * from './monitor_configs'; export * from './monitor_meta_data'; export * from './monitor_types'; -export * from './monitor_types_push'; +export * from './monitor_types_project'; export * from './locations'; diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts similarity index 62% rename from x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts rename to x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts index 52ce5ab0c187a..bf7d414e80272 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_push.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts @@ -8,17 +8,17 @@ import * as t from 'io-ts'; import { ScreenshotOptionCodec } from './monitor_configs'; -export const PushMonitorThrottlingConfigCodec = t.interface({ +export const ProjectMonitorThrottlingConfigCodec = t.interface({ download: t.number, upload: t.number, latency: t.number, }); -export const PushBrowserMonitorCodec = t.intersection([ +export const ProjectBrowserMonitorCodec = t.intersection([ t.interface({ id: t.string, name: t.string, schedule: t.number, content: t.string }), t.partial({ locations: t.array(t.string), - throttling: PushMonitorThrottlingConfigCodec, + throttling: ProjectMonitorThrottlingConfigCodec, screenshots: ScreenshotOptionCodec, tags: t.array(t.string), ignoreHTTPSErrors: t.boolean, @@ -32,14 +32,14 @@ export const PushBrowserMonitorCodec = t.intersection([ }), ]); -export const PushMonitorsRequestCodec = t.interface({ +export const ProjectMonitorsRequestCodec = t.interface({ project: t.string, keep_stale: t.boolean, - monitors: t.array(PushBrowserMonitorCodec), + monitors: t.array(ProjectBrowserMonitorCodec), }); -export type PushMonitorThrottlingConfig = t.TypeOf; +export type ProjectMonitorThrottlingConfig = t.TypeOf; -export type PushBrowserMonitor = t.TypeOf; +export type ProjectBrowserMonitor = t.TypeOf; -export type PushMonitorsRequest = t.TypeOf; +export type ProjectMonitorsRequest = t.TypeOf; diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/lib/telemetry/types.ts b/x-pack/plugins/synthetics/server/legacy_uptime/lib/telemetry/types.ts index 4f637fbe6a7ab..e549fe943aed9 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/lib/telemetry/types.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/lib/telemetry/types.ts @@ -17,7 +17,7 @@ export interface MonitorUpdateEvent { monitorInterval: number; locations: string[]; locationsCount: number; - scriptType?: 'inline' | 'recorder' | 'zip' | 'push'; + scriptType?: 'inline' | 'recorder' | 'zip' | 'project'; revision?: number; errors?: ServiceLocationErrors; configId: string; diff --git a/x-pack/plugins/synthetics/server/routes/index.ts b/x-pack/plugins/synthetics/server/routes/index.ts index 123a228c59f83..0f1e6f01682e6 100644 --- a/x-pack/plugins/synthetics/server/routes/index.ts +++ b/x-pack/plugins/synthetics/server/routes/index.ts @@ -22,11 +22,11 @@ import { testNowMonitorRoute } from './synthetics_service/test_now_monitor'; import { installIndexTemplatesRoute } from './synthetics_service/install_index_templates'; import { editSyntheticsMonitorRoute } from './monitor_cruds/edit_monitor'; import { addSyntheticsMonitorRoute } from './monitor_cruds/add_monitor'; -import { addPublicSyntheticsMonitorRoute } from './monitor_cruds/add_monitor_push'; +import { addSyntheticsProjectMonitorRoute } from './monitor_cruds/add_monitor_project'; import { UMRestApiRouteFactory } from '../legacy_uptime/routes'; export const syntheticsAppRestApiRoutes: UMRestApiRouteFactory[] = [ - addPublicSyntheticsMonitorRoute, + addSyntheticsProjectMonitorRoute, addSyntheticsMonitorRoute, getSyntheticsEnablementRoute, deleteSyntheticsMonitorRoute, diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts similarity index 77% rename from x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts rename to x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts index 2194d8f346231..003f1a34fce19 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_push.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts @@ -6,16 +6,16 @@ */ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../legacy_uptime/lib/lib'; -import { PushBrowserMonitor, Locations } from '../../../common/runtime_types'; +import { ProjectBrowserMonitor, Locations } from '../../../common/runtime_types'; import { UMRestApiRouteFactory } from '../../legacy_uptime/routes/types'; import { API_URLS } from '../../../common/constants'; import { getServiceLocations } from '../../synthetics_service/get_service_locations'; -import { PushMonitorFormatter } from '../../synthetics_service/push_monitor_formatter'; +import { ProjectMonitorFormatter } from '../../synthetics_service/project_monitor_formatter'; -export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ +export const addSyntheticsProjectMonitorRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'PUT', - path: API_URLS.SYNTHETICS_MONITORS_PUSH, + path: API_URLS.SYNTHETICS_MONITORS_PROJECT, validate: { body: schema.object({ project: schema.string(), @@ -24,13 +24,13 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS }), }, handler: async ({ request, response, savedObjectsClient, server }): Promise => { - const monitors = (request.body?.monitors as PushBrowserMonitor[]) || []; + const monitors = (request.body?.monitors as ProjectBrowserMonitor[]) || []; const spaceId = server.spaces.spacesService.getSpaceId(request); const { keep_stale: keepStale, project: projectId } = request.body || {}; const locations: Locations = (await getServiceLocations(server)).locations; const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); - const pushMonitorFormatter = new PushMonitorFormatter({ + const pushMonitorFormatter = new ProjectMonitorFormatter({ projectId, spaceId, keepStale, @@ -41,7 +41,7 @@ export const addPublicSyntheticsMonitorRoute: UMRestApiRouteFactory = (libs: UMS server, }); - await pushMonitorFormatter.configureAllPushMonitors(); + await pushMonitorFormatter.configureAllProjectMonitors(); return response.ok({ body: { diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts index d81a8ce48bd0b..96bca2f2955a3 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts @@ -10,8 +10,8 @@ import { formatErrors } from '@kbn/securitysolution-io-ts-utils'; import { BrowserFieldsCodec, - PushBrowserMonitorCodec, - PushBrowserMonitor, + ProjectBrowserMonitorCodec, + ProjectBrowserMonitor, ConfigKey, DataStream, DataStreamCodec, @@ -82,8 +82,8 @@ export function validateMonitor(monitorFields: MonitorFields): { return { valid: true, reason: '', details: '', payload: monitorFields }; } -export function validatePushMonitor( - monitorFields: PushBrowserMonitor, +export function validateProjectMonitor( + monitorFields: ProjectBrowserMonitor, projectId: string ): { valid: boolean; @@ -111,7 +111,7 @@ export function validatePushMonitor( }; } // Cast it to ICMPCodec to satisfy typing. During runtime, correct codec will be used to decode. - const decodedMonitor = PushBrowserMonitorCodec.decode(monitorFields); + const decodedMonitor = ProjectBrowserMonitorCodec.decode(monitorFields); if (isLeft(decodedMonitor)) { return { diff --git a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts index 351ed4bd66e93..d424280412f4f 100644 --- a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts +++ b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts @@ -113,7 +113,7 @@ describe('monitor upgrade telemetry helpers', () => { }); it.each([ - [ConfigKey.IS_PUSH_MONITOR, true, 'push', false, false], + [ConfigKey.IS_PUSH_MONITOR, true, 'project', false, false], [ConfigKey.SOURCE_INLINE, 'test', 'recorder', true, true], [ConfigKey.SOURCE_INLINE, 'test', 'inline', false, true], [ConfigKey.SOURCE_ZIP_URL, 'test', 'zip', false, false], diff --git a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts index 707c389fbc07c..f4d34f62299d2 100644 --- a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts +++ b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts @@ -144,7 +144,7 @@ export function formatTelemetryDeleteEvent( function getScriptType( attributes: Partial, isInlineScript: boolean -): 'inline' | 'recorder' | 'zip' | 'push' | undefined { +): 'inline' | 'recorder' | 'zip' | 'project' | undefined { switch (true) { case Boolean(attributes[ConfigKey.SOURCE_ZIP_URL]): return 'zip'; @@ -155,7 +155,7 @@ function getScriptType( case Boolean(isInlineScript): return 'inline'; case Boolean(attributes[ConfigKey.IS_PUSH_MONITOR]): - return 'push'; + return 'project'; default: return undefined; } diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index e6477fb0034aa..fd00fb37e8886 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -9,10 +9,10 @@ import { DataStream, ScreenshotOption, Locations, - PushBrowserMonitor, + ProjectBrowserMonitor, } from '../../../common/runtime_types'; import { DEFAULT_FIELDS } from '../../../common/constants/monitor_defaults'; -import { normalizePushedMonitors } from './browser'; +import { normalizeProjectMonitors } from './browser'; describe('browser normalizers', () => { describe('normalize push monitors', () => { @@ -39,7 +39,7 @@ describe('browser normalizers', () => { isServiceManaged: true, }, ]; - const monitors: PushBrowserMonitor[] = [ + const monitors: ProjectBrowserMonitor[] = [ { id: 'test-id-1', screenshots: ScreenshotOption.OFF, @@ -95,7 +95,7 @@ describe('browser normalizers', () => { ]; it('properly normalizes browser monitor', () => { - const actual = normalizePushedMonitors({ + const actual = normalizeProjectMonitors({ locations, monitors, projectId, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index 3e39d0b0dfa8b..1ee4101f6eb3f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -12,7 +12,7 @@ import { ConfigKey, DataStream, Locations, - PushBrowserMonitor, + ProjectBrowserMonitor, ScheduleUnit, } from '../../../common/runtime_types/monitor_management'; @@ -41,14 +41,14 @@ type NormalizedPublicFields = Omit< | ConfigKey.URLS >; -export const normalizePushedMonitor = ({ +export const normalizeProjectMonitor = ({ locations = [], monitor, projectId, namespace, }: { locations: Locations; - monitor: PushBrowserMonitor; + monitor: ProjectBrowserMonitor; projectId: string; namespace: string; }): BrowserFields => { @@ -107,18 +107,18 @@ export const normalizePushedMonitor = ({ }; }; -export const normalizePushedMonitors = ({ +export const normalizeProjectMonitors = ({ locations = [], monitors = [], projectId, namespace, }: { locations: Locations; - monitors: PushBrowserMonitor[]; + monitors: ProjectBrowserMonitor[]; projectId: string; namespace: string; }) => { return monitors.map((monitor) => { - return normalizePushedMonitor({ monitor, locations, projectId, namespace }); + return normalizeProjectMonitor({ monitor, locations, projectId, namespace }); }); }; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts similarity index 90% rename from x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts rename to x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts index 0c4c524c7a319..6552097e154dc 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/push_monitor_formatter.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts @@ -18,19 +18,19 @@ import { SyntheticsMonitorWithSecrets, EncryptedSyntheticsMonitor, ServiceLocationErrors, - PushBrowserMonitor, + ProjectBrowserMonitor, Locations, } from '../../common/runtime_types'; import { syntheticsMonitorType, syntheticsMonitor, } from '../legacy_uptime/lib/saved_objects/synthetics_monitor'; -import { normalizePushedMonitor } from './normalizers/browser'; +import { normalizeProjectMonitor } from './normalizers/browser'; import { formatSecrets, normalizeSecrets } from './utils/secrets'; import { syncNewMonitor } from '../routes/monitor_cruds/add_monitor'; import { syncEditedMonitor } from '../routes/monitor_cruds/edit_monitor'; import { deleteMonitor } from '../routes/monitor_cruds/delete_monitor'; -import { validatePushMonitor } from '../routes/monitor_cruds/monitor_validation'; +import { validateProjectMonitor } from '../routes/monitor_cruds/monitor_validation'; import type { UptimeServerSetup } from '../legacy_uptime/lib/adapters/framework'; interface StaleMonitor { @@ -41,7 +41,7 @@ interface StaleMonitor { type StaleMonitorMap = Record; type FailedMonitors = Array<{ id: string; reason: string; details: string; payload?: object }>; -export class PushMonitorFormatter { +export class ProjectMonitorFormatter { private projectId: string; private spaceId: string; private keepStale: boolean; @@ -49,7 +49,7 @@ export class PushMonitorFormatter { private savedObjectsClient: SavedObjectsClientContract; private encryptedSavedObjectsClient: EncryptedSavedObjectsClient; private staleMonitorsMap: StaleMonitorMap = {}; - private monitors: PushBrowserMonitor[] = []; + private monitors: ProjectBrowserMonitor[] = []; public createdMonitors: string[] = []; public deletedMonitors: string[] = []; public updatedMonitors: string[] = []; @@ -75,7 +75,7 @@ export class PushMonitorFormatter { encryptedSavedObjectsClient: EncryptedSavedObjectsClient; projectId: string; spaceId: string; - monitors: PushBrowserMonitor[]; + monitors: ProjectBrowserMonitor[]; server: UptimeServerSetup; }) { this.projectId = projectId; @@ -89,11 +89,11 @@ export class PushMonitorFormatter { this.projectFilter = `${syntheticsMonitorType}.attributes.${ConfigKey.IS_PUSH_MONITOR}: true AND ${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${this.projectId}"`; } - public configureAllPushMonitors = async () => { - this.staleMonitorsMap = await this.getAllPushMonitorsForProject(); + public configureAllProjectMonitors = async () => { + this.staleMonitorsMap = await this.getAllProjectMonitorsForProject(); await Promise.all( this.monitors.map((monitor) => - this.configurePushMonitor({ + this.configureProjectMonitor({ monitor, }) ) @@ -102,17 +102,17 @@ export class PushMonitorFormatter { await this.handleStaleMonitors(); }; - private configurePushMonitor = async ({ monitor }: { monitor: PushBrowserMonitor }) => { + private configureProjectMonitor = async ({ monitor }: { monitor: ProjectBrowserMonitor }) => { try { // check to see if monitor already exists - const normalizedMonitor = normalizePushedMonitor({ + const normalizedMonitor = normalizeProjectMonitor({ locations: this.locations, monitor, projectId: this.projectId, namespace: this.spaceId, }); - const validationResult = validatePushMonitor(monitor, this.projectId); + const validationResult = validateProjectMonitor(monitor, this.projectId); if (!validationResult.valid) { const { reason: message, details, payload } = validationResult; @@ -162,12 +162,12 @@ export class PushMonitorFormatter { } }; - private getAllPushMonitorsForProject = async (): Promise => { + private getAllProjectMonitorsForProject = async (): Promise => { const staleMonitors: StaleMonitorMap = {}; let page = 1; let totalMonitors = 0; do { - const { total, saved_objects: savedObjects } = await this.getPushMonitorsForProject(page); + const { total, saved_objects: savedObjects } = await this.getProjectMonitorsForProject(page); savedObjects.forEach((savedObject) => { const journeyId = (savedObject.attributes as BrowserFields)[ConfigKey.JOURNEY_ID]; if (journeyId) { @@ -185,7 +185,7 @@ export class PushMonitorFormatter { return staleMonitors; }; - private getPushMonitorsForProject = async (page: number) => { + private getProjectMonitorsForProject = async (page: number) => { return await this.savedObjectsClient.find({ type: syntheticsMonitorType, page, diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts similarity index 69% rename from x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts rename to x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts index a6a7027b66bfc..b9c8e3ba10cdb 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_push.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts @@ -6,7 +6,7 @@ */ import uuid from 'uuid'; import expect from '@kbn/expect'; -import { ConfigKey, PushMonitorsRequest } from '@kbn/synthetics-plugin/common/runtime_types'; +import { ConfigKey, ProjectMonitorsRequest } from '@kbn/synthetics-plugin/common/runtime_types'; import { API_URLS } from '@kbn/synthetics-plugin/common/constants'; import { syntheticsMonitorType } from '@kbn/synthetics-plugin/server/legacy_uptime/lib/saved_objects/synthetics_monitor'; import { FtrProviderContext } from '../../../ftr_provider_context'; @@ -18,9 +18,9 @@ export default function ({ getService }: FtrProviderContext) { const security = getService('security'); const kibanaServer = getService('kibanaServer'); - let pushMonitors: PushMonitorsRequest; + let projectMonitors: ProjectMonitorsRequest; - const setUniqueIds = (request: PushMonitorsRequest) => { + const setUniqueIds = (request: ProjectMonitorsRequest) => { return { ...request, monitors: request.monitors.map((monitor) => ({ ...monitor, id: uuid.v4() })), @@ -48,7 +48,7 @@ export default function ({ getService }: FtrProviderContext) { await supertest .delete(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}/${monitors[0].id}`) .set('kbn-xsrf', 'true') - .send(pushMonitors) + .send(projectMonitors) .expect(200); } } catch (e) { @@ -58,70 +58,70 @@ export default function ({ getService }: FtrProviderContext) { }; beforeEach(() => { - pushMonitors = setUniqueIds(getFixtureJson('push_browser_monitor')); + projectMonitors = setUniqueIds(getFixtureJson('project_browser_monitor')); }); - it('push monitors - returns a list of successfully created monitors', async () => { + it('project monitors - returns a list of successfully created monitors', async () => { try { const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send(pushMonitors); + .send(projectMonitors); expect(apiResponse.body.updatedMonitors).eql([]); expect(apiResponse.body.failedMonitors).eql([]); expect(apiResponse.body.createdMonitors).eql( - pushMonitors.monitors.map((monitor) => monitor.id) + projectMonitors.monitors.map((monitor) => monitor.id) ); } finally { await Promise.all([ - pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - returns a list of successfully updated monitors', async () => { + it('project monitors - returns a list of successfully updated monitors', async () => { try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send(pushMonitors); + .send(projectMonitors); const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send(pushMonitors); + .send(projectMonitors); expect(apiResponse.body.createdMonitors).eql([]); expect(apiResponse.body.failedMonitors).eql([]); expect(apiResponse.body.updatedMonitors).eql( - pushMonitors.monitors.map((monitor) => monitor.id) + projectMonitors.monitors.map((monitor) => monitor.id) ); } finally { await Promise.all([ - pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - does not increment monitor revision unless a change has been made', async () => { + it('project monitors - does not increment monitor revision unless a change has been made', async () => { try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send(pushMonitors); + .send(projectMonitors); await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send(pushMonitors); + .send(projectMonitors); const updatedMonitorsResponse = await Promise.all( - pushMonitors.monitors.map((monitor) => { + projectMonitors.monitors.map((monitor) => { return supertest .get(API_URLS.SYNTHETICS_MONITORS) .query({ query: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) @@ -135,35 +135,35 @@ export default function ({ getService }: FtrProviderContext) { }); } finally { await Promise.all([ - pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - increments monitor revision when a change has been made', async () => { + it('project monitors - increments monitor revision when a change has been made', async () => { try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send(pushMonitors); + .send(projectMonitors); const editedMonitors = { - ...pushMonitors, - monitors: pushMonitors.monitors.map((monitor) => ({ + ...projectMonitors, + monitors: projectMonitors.monitors.map((monitor) => ({ ...monitor, content: 'changed content', })), }; await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') .send(editedMonitors); const updatedMonitorsResponse = await Promise.all( - pushMonitors.monitors.map((monitor) => { + projectMonitors.monitors.map((monitor) => { return supertest .get(API_URLS.SYNTHETICS_MONITORS) .query({ query: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) @@ -177,31 +177,31 @@ export default function ({ getService }: FtrProviderContext) { }); } finally { await Promise.all([ - pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - does not delete monitors when keep stale is true', async () => { - const secondMonitor = { ...pushMonitors.monitors[0], id: 'test-id-2' }; - const testMonitors = [pushMonitors.monitors[0], secondMonitor]; + it('project monitors - does not delete monitors when keep stale is true', async () => { + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') .send({ - ...pushMonitors, + ...projectMonitors, monitors: testMonitors, }) .expect(200); const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send(pushMonitors) + .send(projectMonitors) .expect(200); // does not delete the stale monitor @@ -217,39 +217,39 @@ export default function ({ getService }: FtrProviderContext) { expect(monitors.length).eql(1); - // expect(apiResponse.body.createdMonitors).eql([]); - // expect(apiResponse.body.failedMonitors).eql([]); - // expect(apiResponse.body.deletedMonitors).eql([]); - // expect(apiResponse.body.updatedMonitors).eql([pushMonitors.monitors[0].id]); + expect(apiResponse.body.createdMonitors).eql([]); + expect(apiResponse.body.failedMonitors).eql([]); + expect(apiResponse.body.deletedMonitors).eql([]); + expect(apiResponse.body.updatedMonitors).eql([projectMonitors.monitors[0].id]); expect(apiResponse.body.staleMonitors).eql([secondMonitor.id]); } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - deletes monitors when keep stale is false', async () => { - const secondMonitor = { ...pushMonitors.monitors[0], id: 'test-id-2' }; - const testMonitors = [pushMonitors.monitors[0], secondMonitor]; + it('project monitors - deletes monitors when keep stale is false', async () => { + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') .send({ - ...pushMonitors, + ...projectMonitors, keep_stale: false, monitors: testMonitors, }) .expect(200); - const pushResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + const projectResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send({ ...pushMonitors, keep_stale: false }) + .send({ ...projectMonitors, keep_stale: false }) .expect(200); // expect monitor to have been deleted @@ -265,39 +265,39 @@ export default function ({ getService }: FtrProviderContext) { expect(monitors[0]).eql(undefined); - expect(pushResponse.body.createdMonitors).eql([]); - expect(pushResponse.body.failedMonitors).eql([]); - expect(pushResponse.body.updatedMonitors).eql([pushMonitors.monitors[0].id]); - expect(pushResponse.body.deletedMonitors).eql([secondMonitor.id]); - expect(pushResponse.body.staleMonitors).eql([]); + expect(projectResponse.body.createdMonitors).eql([]); + expect(projectResponse.body.failedMonitors).eql([]); + expect(projectResponse.body.updatedMonitors).eql([projectMonitors.monitors[0].id]); + expect(projectResponse.body.deletedMonitors).eql([secondMonitor.id]); + expect(projectResponse.body.staleMonitors).eql([]); } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - does not delete monitors from different suites when keep stale is false', async () => { - const secondMonitor = { ...pushMonitors.monitors[0], id: 'test-id-2' }; - const testMonitors = [pushMonitors.monitors[0], secondMonitor]; + it('project monitors - does not delete monitors from different suites when keep stale is false', async () => { + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; const testprojectId = 'test-suite-2'; try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') .send({ - ...pushMonitors, + ...projectMonitors, keep_stale: false, monitors: testMonitors, }) .expect(200); - const pushResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + const projectResponse = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send({ ...pushMonitors, keep_stale: false, project: testprojectId }) + .send({ ...projectMonitors, keep_stale: false, project: testprojectId }) .expect(200); // expect monitor not to have been deleted @@ -313,15 +313,15 @@ export default function ({ getService }: FtrProviderContext) { expect(monitors.length).eql(1); - expect(pushResponse.body.createdMonitors).eql([pushMonitors.monitors[0].id]); - expect(pushResponse.body.failedMonitors).eql([]); - expect(pushResponse.body.deletedMonitors).eql([]); - expect(pushResponse.body.updatedMonitors).eql([]); - expect(pushResponse.body.staleMonitors).eql([]); + expect(projectResponse.body.createdMonitors).eql([projectMonitors.monitors[0].id]); + expect(projectResponse.body.failedMonitors).eql([]); + expect(projectResponse.body.deletedMonitors).eql([]); + expect(projectResponse.body.updatedMonitors).eql([]); + expect(projectResponse.body.staleMonitors).eql([]); } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); @@ -333,9 +333,9 @@ export default function ({ getService }: FtrProviderContext) { } }); - it('push monitors - does not delete a monitor from the same suite in a different space', async () => { - const secondMonitor = { ...pushMonitors.monitors[0], id: 'test-id-2' }; - const testMonitors = [pushMonitors.monitors[0], secondMonitor]; + it('project monitors - does not delete a monitor from the same suite in a different space', async () => { + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; const username = 'admin'; const roleName = `synthetics_admin`; const password = `${username}-password`; @@ -359,20 +359,20 @@ export default function ({ getService }: FtrProviderContext) { full_name: 'a kibana user', }); await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .auth(username, password) .set('kbn-xsrf', 'true') .send({ - ...pushMonitors, + ...projectMonitors, keep_stale: false, monitors: testMonitors, }) .expect(200); - const pushResponse = await supertest - .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PUSH}`) + const projectResponse = await supertest + .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT}`) .auth(username, password) .set('kbn-xsrf', 'true') - .send({ ...pushMonitors, keep_stale: false }) + .send({ ...projectMonitors, keep_stale: false }) .expect(200); // expect monitor not to have been deleted const getResponse = await supertest @@ -385,20 +385,26 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); const { monitors } = getResponse.body; expect(monitors.length).eql(1); - expect(pushResponse.body.createdMonitors).eql([pushMonitors.monitors[0].id]); - expect(pushResponse.body.failedMonitors).eql([]); - expect(pushResponse.body.deletedMonitors).eql([]); - expect(pushResponse.body.updatedMonitors).eql([]); - expect(pushResponse.body.staleMonitors).eql([]); + expect(projectResponse.body.createdMonitors).eql([projectMonitors.monitors[0].id]); + expect(projectResponse.body.failedMonitors).eql([]); + expect(projectResponse.body.deletedMonitors).eql([]); + expect(projectResponse.body.updatedMonitors).eql([]); + expect(projectResponse.body.staleMonitors).eql([]); } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project, 'default', username, password); + return deleteMonitor( + monitor.id, + projectMonitors.project, + 'default', + username, + password + ); }), ]); await deleteMonitor( - pushMonitors.monitors[0].id, - pushMonitors.project, + projectMonitors.monitors[0].id, + projectMonitors.project, SPACE_ID, username, password @@ -408,25 +414,25 @@ export default function ({ getService }: FtrProviderContext) { } }); - it('push monitors - validates project id', async () => { + it('project monitors - validates project id', async () => { try { const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') - .send({ ...pushMonitors, project: 'not a valid/ id$?' }); + .send({ ...projectMonitors, project: 'not a valid/ id$?' }); expect(apiResponse.body.updatedMonitors).eql([]); expect(apiResponse.body.failedMonitors).eql([ { details: 'Project id is invalid. Project id: not a valid/ id$?. ', - id: pushMonitors.monitors[0].id, + id: projectMonitors.monitors[0].id, payload: { content: 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', filter: { match: 'check if title is present', }, - id: pushMonitors.monitors[0].id, + id: projectMonitors.monitors[0].id, locations: ['us-east4-a'], name: 'check if title is present', params: {}, @@ -449,22 +455,22 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.body.createdMonitors).eql([]); } finally { await Promise.all([ - pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - validates journey id', async () => { + it('project monitors - validates journey id', async () => { const id = 'not a valid/ id?&'; try { const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') .send({ - ...pushMonitors, - monitors: [{ ...pushMonitors.monitors[0], id }], + ...projectMonitors, + monitors: [{ ...projectMonitors.monitors[0], id }], }); expect(apiResponse.body.updatedMonitors).eql([]); @@ -501,21 +507,21 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.body.createdMonitors).eql([]); } finally { await Promise.all([ - pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - validates monitor type', async () => { + it('project monitors - validates monitor type', async () => { try { const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PUSH) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) .set('kbn-xsrf', 'true') .send({ - ...pushMonitors, - monitors: [{ ...pushMonitors.monitors[0], schedule: '3m', tags: '' }], + ...projectMonitors, + monitors: [{ ...projectMonitors.monitors[0], schedule: '3m', tags: '' }], }); expect(apiResponse.body.updatedMonitors).eql([]); @@ -523,14 +529,14 @@ export default function ({ getService }: FtrProviderContext) { { details: 'Invalid value "3m" supplied to "schedule" | Invalid value "" supplied to "tags"', - id: pushMonitors.monitors[0].id, + id: projectMonitors.monitors[0].id, payload: { content: 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', filter: { match: 'check if title is present', }, - id: pushMonitors.monitors[0].id, + id: projectMonitors.monitors[0].id, locations: ['us-east4-a'], name: 'check if title is present', params: {}, @@ -552,14 +558,14 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.body.createdMonitors).eql([]); } finally { await Promise.all([ - pushMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, pushMonitors.project); + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); }), ]); } }); - it('push monitors - saves space as data stream namespace', async () => { + it('project monitors - saves space as data stream namespace', async () => { const username = 'admin'; const roleName = `synthetics_admin`; const password = `${username}-password`; @@ -583,17 +589,17 @@ export default function ({ getService }: FtrProviderContext) { full_name: 'a kibana user', }); await supertest - .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PUSH}`) + .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT}`) .auth(username, password) .set('kbn-xsrf', 'true') - .send(pushMonitors) + .send(projectMonitors) .expect(200); // expect monitor not to have been deleted const getResponse = await supertest .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) .auth(username, password) .query({ - query: `${syntheticsMonitorType}.attributes.journey_id: ${pushMonitors.monitors[0].id}`, + query: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, }) .set('kbn-xsrf', 'true') .expect(200); @@ -602,8 +608,8 @@ export default function ({ getService }: FtrProviderContext) { expect(monitors[0].attributes[ConfigKey.NAMESPACE]).eql(SPACE_ID); } finally { await deleteMonitor( - pushMonitors.monitors[0].id, - pushMonitors.project, + projectMonitors.monitors[0].id, + projectMonitors.project, SPACE_ID, username, password @@ -613,7 +619,7 @@ export default function ({ getService }: FtrProviderContext) { } }); - it('push monitors - formats custom id appropriately', async () => { + it('project monitors - formats custom id appropriately', async () => { const username = 'admin'; const roleName = `synthetics_admin`; const password = `${username}-password`; @@ -637,29 +643,29 @@ export default function ({ getService }: FtrProviderContext) { full_name: 'a kibana user', }); await supertest - .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PUSH}`) + .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT}`) .auth(username, password) .set('kbn-xsrf', 'true') - .send(pushMonitors) + .send(projectMonitors) .expect(200); // expect monitor not to have been deleted const getResponse = await supertest .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) .auth(username, password) .query({ - query: `${syntheticsMonitorType}.attributes.journey_id: ${pushMonitors.monitors[0].id}`, + query: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, }) .set('kbn-xsrf', 'true') .expect(200); const { monitors } = getResponse.body; expect(monitors.length).eql(1); expect(monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]).eql( - `${pushMonitors.monitors[0].id}-${pushMonitors.project}-${SPACE_ID}` + `${projectMonitors.monitors[0].id}-${projectMonitors.project}-${SPACE_ID}` ); } finally { await deleteMonitor( - pushMonitors.monitors[0].id, - pushMonitors.project, + projectMonitors.monitors[0].id, + projectMonitors.project, SPACE_ID, username, password diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_browser_monitor.json similarity index 100% rename from x-pack/test/api_integration/apis/uptime/rest/fixtures/push_browser_monitor.json rename to x-pack/test/api_integration/apis/uptime/rest/fixtures/project_browser_monitor.json diff --git a/x-pack/test/api_integration/apis/uptime/rest/index.ts b/x-pack/test/api_integration/apis/uptime/rest/index.ts index 648701e52d8d1..891076c1730bc 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/index.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/index.ts @@ -75,7 +75,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { describe('uptime CRUD routes', () => { loadTestFile(require.resolve('./get_monitor')); loadTestFile(require.resolve('./add_monitor')); - loadTestFile(require.resolve('./add_monitor_push')); + loadTestFile(require.resolve('./add_monitor_project')); loadTestFile(require.resolve('./edit_monitor')); loadTestFile(require.resolve('./delete_monitor')); loadTestFile(require.resolve('./synthetics_enablement')); From bbe93f3080917d36086c146077a6977685f7c7f5 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Thu, 19 May 2022 13:49:36 -0400 Subject: [PATCH 45/68] adjust tests --- .../server/synthetics_service/normalizers/browser.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index fd00fb37e8886..debac59b17c02 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -139,6 +139,7 @@ describe('browser normalizers', () => { namespace: 'test-space', original_space: 'test-space', custom_heartbeat_id: 'test-id-3-test-project-id-test-space', + timeout: null, }, { ...DEFAULT_FIELDS[DataStream.BROWSER], @@ -188,6 +189,7 @@ describe('browser normalizers', () => { namespace: 'test-space', original_space: 'test-space', custom_heartbeat_id: 'test-id-3-test-project-id-test-space', + timeout: null, }, { ...DEFAULT_FIELDS[DataStream.BROWSER], @@ -237,6 +239,7 @@ describe('browser normalizers', () => { namespace: 'test-space', original_space: 'test-space', custom_heartbeat_id: 'test-id-3-test-project-id-test-space', + timeout: null, }, ]); }); From f6c537866c06588671e0dd763584aa3dc818ef03 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Thu, 19 May 2022 14:14:16 -0400 Subject: [PATCH 46/68] rename is_push_monitor to source_type --- .../synthetics/common/constants/monitor_defaults.ts | 3 ++- .../synthetics/common/constants/monitor_management.ts | 2 +- .../runtime_types/monitor_management/monitor_configs.ts | 7 +++++++ .../runtime_types/monitor_management/monitor_types.ts | 3 ++- .../components/fleet_package/browser/formatters.ts | 1 - .../components/fleet_package/browser/normalizers.ts | 1 - .../components/fleet_package/common/formatters.ts | 1 + .../components/fleet_package/common/normalizers.ts | 1 + .../legacy_uptime/lib/saved_objects/synthetics_monitor.ts | 4 ++-- .../monitor_validation.test.ts | 5 +++-- .../server/routes/telemetry/monitor_upgrade_sender.test.ts | 2 +- .../server/routes/telemetry/monitor_upgrade_sender.ts | 3 ++- .../server/synthetics_service/formatters/browser.ts | 1 - .../server/synthetics_service/formatters/common.ts | 1 + .../server/synthetics_service/formatters/format_configs.ts | 3 ++- .../server/synthetics_service/normalizers/browser.test.ts | 6 +++--- .../server/synthetics_service/normalizers/browser.ts | 3 ++- .../server/synthetics_service/project_monitor_formatter.ts | 2 +- .../apis/uptime/rest/fixtures/browser_monitor.json | 3 ++- .../apis/uptime/rest/fixtures/http_monitor.json | 3 ++- .../apis/uptime/rest/fixtures/icmp_monitor.json | 3 ++- .../apis/uptime/rest/fixtures/tcp_monitor.json | 3 ++- 22 files changed, 39 insertions(+), 22 deletions(-) rename x-pack/plugins/synthetics/server/routes/{synthetics_service => monitor_cruds}/monitor_validation.test.ts (99%) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts index 96c6463d3cea3..82d1abec56e77 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -18,6 +18,7 @@ import { ResponseBodyIndexPolicy, ScheduleUnit, ScreenshotOption, + SourceType, TCPAdvancedFields, TCPSimpleFields, TLSFields, @@ -41,6 +42,7 @@ export const DEFAULT_COMMON_FIELDS: CommonFields = { [ConfigKey.NAME]: '', [ConfigKey.LOCATIONS]: [], [ConfigKey.NAMESPACE]: DEFAULT_NAMESPACE_STRING, + [ConfigKey.SOURCE_TYPE]: SourceType.UI, }; export const DEFAULT_BROWSER_ADVANCED_FIELDS: BrowserAdvancedFields = { @@ -61,7 +63,6 @@ export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { [ConfigKey.JOURNEY_ID]: '', [ConfigKey.PROJECT_ID]: '', [ConfigKey.PLAYWRIGHT_OPTIONS]: '', - [ConfigKey.IS_PUSH_MONITOR]: false, [ConfigKey.METADATA]: { script_source: { is_generated_script: false, diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index e0ae968d583c2..6d4f1bc43f892 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -12,7 +12,7 @@ export enum ConfigKey { ENABLED = 'enabled', HOSTS = 'hosts', IGNORE_HTTPS_ERRORS = 'ignore_https_errors', - IS_PUSH_MONITOR = 'is_push_monitor', + SOURCE_TYPE = 'source_type', JOURNEY_FILTERS_MATCH = 'filter_journeys.match', JOURNEY_FILTERS_TAGS = 'filter_journeys.tags', JOURNEY_ID = 'journey_id', diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_configs.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_configs.ts index ac917dda0e142..4d1e22ffaea3b 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_configs.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_configs.ts @@ -119,3 +119,10 @@ export enum ThrottlingSuffix { export const ThrottlingSuffixCodec = tEnum('ThrottlingSuffix', ThrottlingSuffix); export type ThrottlingSuffixType = t.TypeOf; + +export enum SourceType { + UI = 'ui', + PROJECT = 'project', +} + +export const SourceTypeCodec = tEnum('SourceType', SourceType); diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index a26d54472ee8f..5b4b5a65cee09 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -15,6 +15,7 @@ import { ModeCodec, ResponseBodyIndexPolicyCodec, ScheduleUnitCodec, + SourceTypeCodec, TLSVersionCodec, VerificationModeCodec, } from './monitor_configs'; @@ -76,6 +77,7 @@ export const CommonFieldsCodec = t.intersection([ t.partial({ [ConfigKey.TIMEOUT]: t.union([t.string, t.null]), [ConfigKey.REVISION]: t.number, + [ConfigKey.SOURCE_TYPE]: SourceTypeCodec, }), ]); @@ -211,7 +213,6 @@ export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ [ConfigKey.PLAYWRIGHT_OPTIONS]: t.string, [ConfigKey.JOURNEY_ID]: t.string, [ConfigKey.PROJECT_ID]: t.string, - [ConfigKey.IS_PUSH_MONITOR]: t.boolean, [ConfigKey.ORIGINAL_SPACE]: t.string, [ConfigKey.CUSTOM_HEARTBEAT_ID]: t.string, }), diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts index 8519148f52364..a579a2db298a0 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts @@ -72,7 +72,6 @@ export const browserFormatters: BrowserFormatMap = { arrayToJsonFormatter(fields[ConfigKey.JOURNEY_FILTERS_TAGS]), [ConfigKey.THROTTLING_CONFIG]: throttlingFormatter, [ConfigKey.IGNORE_HTTPS_ERRORS]: null, - [ConfigKey.IS_PUSH_MONITOR]: null, [ConfigKey.JOURNEY_ID]: null, [ConfigKey.PROJECT_ID]: null, [ConfigKey.PLAYWRIGHT_OPTIONS]: null, 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 index 06938fba3ecf2..b5f87ae272837 100644 --- 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 @@ -80,7 +80,6 @@ export const browserNormalizers: BrowserNormalizerMap = { [ConfigKey.SCREENSHOTS]: getBrowserNormalizer(ConfigKey.SCREENSHOTS), [ConfigKey.SYNTHETICS_ARGS]: getBrowserJsonToJavascriptNormalizer(ConfigKey.SYNTHETICS_ARGS), [ConfigKey.IS_THROTTLING_ENABLED]: isThrottlingEnabledNormalizer, - [ConfigKey.IS_PUSH_MONITOR]: getBrowserNormalizer(ConfigKey.IS_PUSH_MONITOR), [ConfigKey.DOWNLOAD_SPEED]: getThrottlingParamNormalizer(ConfigKey.DOWNLOAD_SPEED), [ConfigKey.UPLOAD_SPEED]: getThrottlingParamNormalizer(ConfigKey.UPLOAD_SPEED), [ConfigKey.LATENCY]: getThrottlingParamNormalizer(ConfigKey.LATENCY), diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts index a86894c3d7a48..5c7c49a678d72 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts @@ -25,6 +25,7 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.TIMEOUT]: (fields) => secondsToCronFormatter(fields[ConfigKey.TIMEOUT] || undefined), [ConfigKey.NAMESPACE]: null, [ConfigKey.REVISION]: null, + [ConfigKey.SOURCE_TYPE]: null, }; export const arrayToJsonFormatter = (value: string[] = []) => diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts index 0119b415faed8..13f19c94d9b66 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts @@ -87,4 +87,5 @@ export const commonNormalizers: CommonNormalizerMap = { [ConfigKey.NAMESPACE]: (fields) => fields?.[ConfigKey.NAMESPACE]?.value ?? DEFAULT_NAMESPACE_STRING, [ConfigKey.REVISION]: getCommonNormalizer(ConfigKey.REVISION), + [ConfigKey.SOURCE_TYPE]: getCommonNormalizer(ConfigKey.SOURCE_TYPE), }; diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts b/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts index d31caa03f7334..1b46681bd116f 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts @@ -50,8 +50,8 @@ export const syntheticsMonitor: SavedObjectsType = { project_id: { type: 'keyword', }, - is_push_monitor: { - type: 'boolean', + source_type: { + type: 'keyword', }, }, }, diff --git a/x-pack/plugins/synthetics/server/routes/synthetics_service/monitor_validation.test.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts similarity index 99% rename from x-pack/plugins/synthetics/server/routes/synthetics_service/monitor_validation.test.ts rename to x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts index 3633310986501..3e78332a2ffeb 100644 --- a/x-pack/plugins/synthetics/server/routes/synthetics_service/monitor_validation.test.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts @@ -21,6 +21,7 @@ import { MonitorFields, ResponseBodyIndexPolicy, ScheduleUnit, + SourceType, TCPAdvancedFields, TCPFields, TCPSimpleFields, @@ -29,7 +30,7 @@ import { VerificationMode, ZipUrlTLSFields, } from '../../../common/runtime_types'; -import { validateMonitor } from '../monitor_cruds/monitor_validation'; +import { validateMonitor } from './monitor_validation'; describe('validateMonitor', () => { let testSchedule; @@ -160,7 +161,7 @@ describe('validateMonitor', () => { testBrowserSimpleFields = { ...testZipUrlTLSFields, ...testCommonFields, - [ConfigKey.IS_PUSH_MONITOR]: false, + [ConfigKey.SOURCE_TYPE]: SourceType.PROJECT, [ConfigKey.JOURNEY_ID]: '', [ConfigKey.PROJECT_ID]: '', [ConfigKey.METADATA]: testMetaData, diff --git a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts index d424280412f4f..a3c96341ee26c 100644 --- a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts +++ b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts @@ -113,7 +113,7 @@ describe('monitor upgrade telemetry helpers', () => { }); it.each([ - [ConfigKey.IS_PUSH_MONITOR, true, 'project', false, false], + [ConfigKey.SOURCE_TYPE, true, 'project', false, false], [ConfigKey.SOURCE_INLINE, 'test', 'recorder', true, true], [ConfigKey.SOURCE_INLINE, 'test', 'inline', false, true], [ConfigKey.SOURCE_ZIP_URL, 'test', 'zip', false, false], diff --git a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts index f4d34f62299d2..9befa834ebad5 100644 --- a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts +++ b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts @@ -13,6 +13,7 @@ import { EncryptedSyntheticsMonitor, ConfigKey, ServiceLocationErrors, + SourceType, } from '../../../common/runtime_types'; import type { MonitorUpdateEvent } from '../../legacy_uptime/lib/telemetry/types'; @@ -154,7 +155,7 @@ function getScriptType( return 'recorder'; case Boolean(isInlineScript): return 'inline'; - case Boolean(attributes[ConfigKey.IS_PUSH_MONITOR]): + case attributes[ConfigKey.SOURCE_TYPE] === SourceType.PROJECT: return 'project'; default: return undefined; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts index 0e7aee9cf0f46..16ae8625e129d 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts @@ -55,7 +55,6 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.JOURNEY_FILTERS_TAGS]: (fields) => arrayFormatter(fields[ConfigKey.JOURNEY_FILTERS_TAGS]), [ConfigKey.IGNORE_HTTPS_ERRORS]: null, - [ConfigKey.IS_PUSH_MONITOR]: null, [ConfigKey.JOURNEY_ID]: null, [ConfigKey.PROJECT_ID]: null, [ConfigKey.PLAYWRIGHT_OPTIONS]: null, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts index 8756ea9c67c8e..ea83891fbc0e2 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts @@ -26,6 +26,7 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.TIMEOUT]: (fields) => secondsToCronFormatter(fields[ConfigKey.TIMEOUT] || undefined), [ConfigKey.NAMESPACE]: null, [ConfigKey.REVISION]: null, + [ConfigKey.SOURCE_TYPE]: null, }; export const arrayFormatter = (value: string[] = []) => (value.length ? value : null); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts index df19a9d739cf7..6b50034cfabeb 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts @@ -10,7 +10,7 @@ import { ConfigKey, MonitorFields } from '../../../common/runtime_types'; import { formatters } from '.'; const UI_KEYS_TO_SKIP = [ - ConfigKey.IS_PUSH_MONITOR, + ConfigKey.SOURCE_TYPE, ConfigKey.JOURNEY_ID, ConfigKey.PROJECT_ID, ConfigKey.METADATA, @@ -20,6 +20,7 @@ const UI_KEYS_TO_SKIP = [ ConfigKey.IS_THROTTLING_ENABLED, ConfigKey.LOCATIONS, ConfigKey.REVISION, + ConfigKey.CUSTOM_HEARTBEAT_ID, 'secrets', ]; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index debac59b17c02..89eff08a494be 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -106,7 +106,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-1', ignore_https_errors: true, - is_push_monitor: true, + source_type: 'project', locations: [ { geo: { @@ -145,7 +145,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-2', ignore_https_errors: false, - is_push_monitor: true, + source_type: 'project', locations: [ { geo: { @@ -195,7 +195,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-3', ignore_https_errors: false, - is_push_monitor: true, + source_type: 'project', locations: [ { geo: { diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index 1ee4101f6eb3f..0579842d228f7 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -14,6 +14,7 @@ import { Locations, ProjectBrowserMonitor, ScheduleUnit, + SourceType, } from '../../../common/runtime_types/monitor_management'; /* Represents all of the push-monitor related fields that need to be @@ -55,7 +56,7 @@ export const normalizeProjectMonitor = ({ const defaultFields = DEFAULT_FIELDS[DataStream.BROWSER]; const normalizedFields: NormalizedPublicFields = { [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, - [ConfigKey.IS_PUSH_MONITOR]: true, + [ConfigKey.SOURCE_TYPE]: SourceType.PROJECT, [ConfigKey.NAME]: monitor.name || '', [ConfigKey.SCHEDULE]: { number: `${monitor.schedule}`, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts index 6552097e154dc..3060075701ec3 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts @@ -86,7 +86,7 @@ export class ProjectMonitorFormatter { this.encryptedSavedObjectsClient = encryptedSavedObjectsClient; this.monitors = monitors; this.server = server; - this.projectFilter = `${syntheticsMonitorType}.attributes.${ConfigKey.IS_PUSH_MONITOR}: true AND ${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${this.projectId}"`; + this.projectFilter = `${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${this.projectId}"`; } public configureAllProjectMonitors = async () => { diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json index 123c5c1241adc..b29f22d44e9ca 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json @@ -42,5 +42,6 @@ "throttling.config": "5d/3u/20l", "locations": [], "name": "Test HTTP Monitor 03", - "namespace": "testnamespace" + "namespace": "testnamespace", + "source_type": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json index 11d4dc67ff585..74c3b2c0dbfee 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json @@ -60,5 +60,6 @@ "isServiceManaged": true }], "namespace": "testnamespace", - "revision": 1 + "revision": 1, + "source_type": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json index 60816bb4538e5..aa5bee6a1c5c0 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json @@ -32,5 +32,6 @@ "TLSv1.3" ], "name": "Test HTTP Monitor 04", - "namespace": "testnamespace" + "namespace": "testnamespace", + "source_type": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json index 79476fc442b18..441cb6f71ed33 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json @@ -28,5 +28,6 @@ "TLSv1.3" ], "name": "Test HTTP Monitor 04", - "namespace": "testnamespace" + "namespace": "testnamespace", + "source_type": "ui" } From ecd04e1cc9101c80d7e9ed15e043c59cbf5005e8 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Thu, 19 May 2022 16:07:29 -0400 Subject: [PATCH 47/68] adjust tests --- .../server/synthetics_service/normalizers/browser.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index 89eff08a494be..a5150bcbaf97f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -138,7 +138,7 @@ describe('browser normalizers', () => { project_id: projectId, namespace: 'test-space', original_space: 'test-space', - custom_heartbeat_id: 'test-id-3-test-project-id-test-space', + custom_heartbeat_id: 'test-id-1-test-project-id-test-space', timeout: null, }, { @@ -188,7 +188,7 @@ describe('browser normalizers', () => { project_id: projectId, namespace: 'test-space', original_space: 'test-space', - custom_heartbeat_id: 'test-id-3-test-project-id-test-space', + custom_heartbeat_id: 'test-id-2-test-project-id-test-space', timeout: null, }, { From 4f02c1841a01b1ed632c17f10c438c37db5b6704 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Thu, 19 May 2022 16:12:06 -0400 Subject: [PATCH 48/68] adjust test --- .../server/routes/telemetry/monitor_upgrade_sender.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts index a3c96341ee26c..50c5298aa4607 100644 --- a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts +++ b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts @@ -13,6 +13,7 @@ import { ConfigKey, DataStream, ScheduleUnit, + SourceType, } from '../../../common/runtime_types/monitor_management'; import { DEFAULT_FIELDS } from '../../../common/constants/monitor_defaults'; @@ -113,7 +114,7 @@ describe('monitor upgrade telemetry helpers', () => { }); it.each([ - [ConfigKey.SOURCE_TYPE, true, 'project', false, false], + [ConfigKey.SOURCE_TYPE, SourceType.PROJECT, 'project', false, false], [ConfigKey.SOURCE_INLINE, 'test', 'recorder', true, true], [ConfigKey.SOURCE_INLINE, 'test', 'inline', false, true], [ConfigKey.SOURCE_ZIP_URL, 'test', 'zip', false, false], From ff282fabe91eca99d2d72587db5d168b1049d0fb Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 20 May 2022 10:35:21 -0400 Subject: [PATCH 49/68] update project monitor source --- .../synthetics/common/constants/monitor_management.ts | 2 +- .../server/synthetics_service/normalizers/browser.test.ts | 6 +++--- .../apis/uptime/rest/fixtures/browser_monitor.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index 6d4f1bc43f892..b52c20eab8c0b 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -43,7 +43,7 @@ export enum ConfigKey { REVISION = 'revision', SCHEDULE = 'schedule', SCREENSHOTS = 'screenshots', - SOURCE_PUSH = 'source.pushed.content', + SOURCE_PUSH = 'source.project.content', SOURCE_INLINE = 'source.inline.script', SOURCE_ZIP_URL = 'source.zip_url.url', SOURCE_ZIP_USERNAME = 'source.zip_url.username', diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index a5150bcbaf97f..36a746ed4adf0 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -126,7 +126,7 @@ describe('browser normalizers', () => { }, screenshots: 'off', 'service.name': 'cart-service', - 'source.pushed.content': 'test content 1', + 'source.project.content': 'test content 1', tags: ['tag1', 'tag2'], 'throttling.config': '5d/10u/20l', 'throttling.download_speed': '5', @@ -177,7 +177,7 @@ describe('browser normalizers', () => { }, screenshots: 'on', 'service.name': 'bean-service', - 'source.pushed.content': 'test content 2', + 'source.project.content': 'test content 2', tags: ['tag3', 'tag4'], 'throttling.config': '10d/15u/18l', 'throttling.download_speed': '10', @@ -227,7 +227,7 @@ describe('browser normalizers', () => { }, screenshots: 'on', 'service.name': 'bean-service', - 'source.pushed.content': 'test content 3', + 'source.project.content': 'test content 3', tags: ['tag3', 'tag4'], 'throttling.config': '10d/15u/18l', 'throttling.download_speed': '10', diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json index b29f22d44e9ca..8873633020e00 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json @@ -27,7 +27,7 @@ "source.zip_url.folder": "", "source.zip_url.proxy_url": "", "source.inline.script": "step(\"Visit /users api route\", async () => {\\n const response = await page.goto('https://nextjs-test-synthetics.vercel.app/api/users');\\n expect(response.status()).toEqual(200);\\n});", - "source.pushed.content": "", + "source.project.content": "", "is_push_monitor": false, "params": "", "screenshots": "on", From 7f48719a4ef940a49afc68e8b27ee1141e518c0a Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 20 May 2022 10:43:36 -0400 Subject: [PATCH 50/68] add monitor.source --- .../synthetics/common/constants/monitor_management.ts | 2 +- .../legacy_uptime/lib/saved_objects/synthetics_monitor.ts | 2 +- .../server/synthetics_service/formatters/common.ts | 4 ++-- .../server/synthetics_service/formatters/format_configs.ts | 1 - .../server/synthetics_service/normalizers/browser.test.ts | 6 +++--- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index b52c20eab8c0b..4fc23c3b45c72 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -12,7 +12,7 @@ export enum ConfigKey { ENABLED = 'enabled', HOSTS = 'hosts', IGNORE_HTTPS_ERRORS = 'ignore_https_errors', - SOURCE_TYPE = 'source_type', + SOURCE_TYPE = 'monitor.source', JOURNEY_FILTERS_MATCH = 'filter_journeys.match', JOURNEY_FILTERS_TAGS = 'filter_journeys.tags', JOURNEY_ID = 'journey_id', diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts b/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts index 1b46681bd116f..37b0bb05d2361 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts @@ -50,7 +50,7 @@ export const syntheticsMonitor: SavedObjectsType = { project_id: { type: 'keyword', }, - source_type: { + 'monitor.source': { type: 'keyword', }, }, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts index ea83891fbc0e2..2bc323b25ff1f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { CommonFields, ConfigKey, MonitorFields } from '../../../common/runtime_types'; +import { CommonFields, ConfigKey, MonitorFields, SourceType } from '../../../common/runtime_types'; export type FormattedValue = boolean | string | string[] | Record | null; @@ -26,7 +26,7 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.TIMEOUT]: (fields) => secondsToCronFormatter(fields[ConfigKey.TIMEOUT] || undefined), [ConfigKey.NAMESPACE]: null, [ConfigKey.REVISION]: null, - [ConfigKey.SOURCE_TYPE]: null, + [ConfigKey.SOURCE_TYPE]: (fields) => fields[ConfigKey.SOURCE_TYPE] || SourceType.UI, }; export const arrayFormatter = (value: string[] = []) => (value.length ? value : null); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts index 6b50034cfabeb..82262e60c4b24 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts @@ -10,7 +10,6 @@ import { ConfigKey, MonitorFields } from '../../../common/runtime_types'; import { formatters } from '.'; const UI_KEYS_TO_SKIP = [ - ConfigKey.SOURCE_TYPE, ConfigKey.JOURNEY_ID, ConfigKey.PROJECT_ID, ConfigKey.METADATA, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index 36a746ed4adf0..956974e41b457 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -106,7 +106,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-1', ignore_https_errors: true, - source_type: 'project', + 'monitor.source': 'project', locations: [ { geo: { @@ -145,7 +145,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-2', ignore_https_errors: false, - source_type: 'project', + 'monitor.source': 'project', locations: [ { geo: { @@ -195,7 +195,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-3', ignore_https_errors: false, - source_type: 'project', + 'monitor.source': 'project', locations: [ { geo: { From 463de3f5cfe40c17f633a6b74f0667e6e045bc0c Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 20 May 2022 14:22:59 -0400 Subject: [PATCH 51/68] adjust tests --- .../apis/uptime/rest/fixtures/browser_monitor.json | 2 +- .../api_integration/apis/uptime/rest/fixtures/http_monitor.json | 2 +- .../api_integration/apis/uptime/rest/fixtures/icmp_monitor.json | 2 +- .../api_integration/apis/uptime/rest/fixtures/tcp_monitor.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json index 8873633020e00..c870f181ee13b 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json @@ -43,5 +43,5 @@ "locations": [], "name": "Test HTTP Monitor 03", "namespace": "testnamespace", - "source_type": "ui" + "monitor.source": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json index 74c3b2c0dbfee..995cafb7d2e14 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json @@ -61,5 +61,5 @@ }], "namespace": "testnamespace", "revision": 1, - "source_type": "ui" + "monitor.source": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json index aa5bee6a1c5c0..bc1cfb49d4537 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json @@ -33,5 +33,5 @@ ], "name": "Test HTTP Monitor 04", "namespace": "testnamespace", - "source_type": "ui" + "monitor.source": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json index 441cb6f71ed33..622ee1a73692c 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json @@ -29,5 +29,5 @@ ], "name": "Test HTTP Monitor 04", "namespace": "testnamespace", - "source_type": "ui" + "monitor.source": "ui" } From 32e9cac71ead0b5609fcd799eaff080f5a56e09b Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 20 May 2022 15:05:28 -0400 Subject: [PATCH 52/68] adjust validation logic --- .../monitor_management/monitor_types_project.ts | 9 +++++++-- .../routes/monitor_cruds/monitor_validation.ts | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts index bf7d414e80272..7157aa7eda848 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts @@ -15,9 +15,14 @@ export const ProjectMonitorThrottlingConfigCodec = t.interface({ }); export const ProjectBrowserMonitorCodec = t.intersection([ - t.interface({ id: t.string, name: t.string, schedule: t.number, content: t.string }), - t.partial({ + t.interface({ + id: t.string, + name: t.string, + schedule: t.number, + content: t.string, locations: t.array(t.string), + }), + t.partial({ throttling: ProjectMonitorThrottlingConfigCodec, screenshots: ScreenshotOptionCodec, tags: t.array(t.string), diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts index 96bca2f2955a3..b395e83acc9ba 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts @@ -100,6 +100,10 @@ export function validateProjectMonitor( const journeyIdError = !isJourneyIdValid ? `Journey id is invalid. Journey id: ${monitorFields.id}.` : ''; + const locationsError = + monitorFields.locations && monitorFields.locations.length === 0 + ? 'Invalid value "[]" supplied to field "locations"' + : ''; if (!isProjectIdValid || !isJourneyIdValid) { return { @@ -117,7 +121,18 @@ export function validateProjectMonitor( return { valid: false, reason: `Failed to save or update monitor. Configuration is not valid`, - details: formatErrors(decodedMonitor.left).join(' | '), + details: [...formatErrors(decodedMonitor.left), locationsError] + .filter((error) => error !== '') + .join(' | '), + payload: monitorFields, + }; + } + + if (locationsError) { + return { + valid: false, + reason: `Failed to save or update monitor. Configuration is not valid`, + details: locationsError, payload: monitorFields, }; } From 28235489682ef55fbd6d931e5e481b2a09e1c1ec Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 20 May 2022 15:30:26 -0400 Subject: [PATCH 53/68] rename config key --- .../plugins/synthetics/common/constants/monitor_defaults.ts | 2 +- .../plugins/synthetics/common/constants/monitor_management.ts | 4 ++-- .../common/runtime_types/monitor_management/monitor_types.ts | 2 +- .../components/fleet_package/browser/formatters.ts | 2 +- .../components/fleet_package/browser/normalizers.ts | 2 +- .../server/routes/monitor_cruds/monitor_validation.test.ts | 2 +- .../server/synthetics_service/formatters/browser.ts | 2 +- .../server/synthetics_service/normalizers/browser.ts | 3 ++- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts index 82d1abec56e77..2ce87e1cb96cb 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -78,7 +78,7 @@ export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { number: '10', }, [ConfigKey.SOURCE_INLINE]: '', - [ConfigKey.SOURCE_PUSH]: '', + [ConfigKey.SOURCE_PROJECT_CONTENT]: '', [ConfigKey.SOURCE_ZIP_URL]: '', [ConfigKey.SOURCE_ZIP_USERNAME]: '', [ConfigKey.SOURCE_ZIP_PASSWORD]: '', diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index 4fc23c3b45c72..b212cfcb7e377 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -43,7 +43,7 @@ export enum ConfigKey { REVISION = 'revision', SCHEDULE = 'schedule', SCREENSHOTS = 'screenshots', - SOURCE_PUSH = 'source.project.content', + SOURCE_PROJECT_CONTENT = 'source.project.content', SOURCE_INLINE = 'source.inline.script', SOURCE_ZIP_URL = 'source.zip_url.url', SOURCE_ZIP_USERNAME = 'source.zip_url.username', @@ -87,7 +87,7 @@ export const secretKeys = [ ConfigKey.RESPONSE_HEADERS_CHECK, ConfigKey.RESPONSE_RECEIVE_CHECK, ConfigKey.SOURCE_INLINE, - ConfigKey.SOURCE_PUSH, + ConfigKey.SOURCE_PROJECT_CONTENT, ConfigKey.SOURCE_ZIP_USERNAME, ConfigKey.SOURCE_ZIP_PASSWORD, ConfigKey.SYNTHETICS_ARGS, diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index 5b4b5a65cee09..e50f7b0617d3b 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -225,7 +225,7 @@ export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ export const BrowserSensitiveSimpleFieldsCodec = t.intersection([ t.interface({ [ConfigKey.SOURCE_INLINE]: t.string, - [ConfigKey.SOURCE_PUSH]: t.string, + [ConfigKey.SOURCE_PROJECT_CONTENT]: t.string, [ConfigKey.SOURCE_ZIP_USERNAME]: t.string, [ConfigKey.SOURCE_ZIP_PASSWORD]: t.string, [ConfigKey.PARAMS]: t.string, diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts index a579a2db298a0..f69cf713b3907 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts @@ -45,7 +45,7 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.SOURCE_ZIP_PASSWORD]: null, [ConfigKey.SOURCE_ZIP_FOLDER]: null, [ConfigKey.SOURCE_ZIP_PROXY_URL]: null, - [ConfigKey.SOURCE_PUSH]: null, + [ConfigKey.SOURCE_PROJECT_CONTENT]: null, [ConfigKey.SOURCE_INLINE]: (fields) => stringToJsonFormatter(fields[ConfigKey.SOURCE_INLINE]), [ConfigKey.PARAMS]: null, [ConfigKey.SCREENSHOTS]: null, 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 index b5f87ae272837..6d1e51a66f49a 100644 --- 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 @@ -73,7 +73,7 @@ export const browserNormalizers: BrowserNormalizerMap = { [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_PUSH]: getBrowserNormalizer(ConfigKey.SOURCE_PUSH), + [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), diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts index 3e78332a2ffeb..8f24719a6cefb 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts @@ -166,7 +166,7 @@ describe('validateMonitor', () => { [ConfigKey.PROJECT_ID]: '', [ConfigKey.METADATA]: testMetaData, [ConfigKey.SOURCE_INLINE]: '', - [ConfigKey.SOURCE_PUSH]: '', + [ConfigKey.SOURCE_PROJECT_CONTENT]: '', [ConfigKey.SOURCE_ZIP_URL]: '', [ConfigKey.SOURCE_ZIP_FOLDER]: '', [ConfigKey.SOURCE_ZIP_USERNAME]: 'test-username', diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts index 16ae8625e129d..88e6d2f367896 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts @@ -36,7 +36,7 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.SOURCE_ZIP_PASSWORD]: null, [ConfigKey.SOURCE_ZIP_FOLDER]: null, [ConfigKey.SOURCE_ZIP_PROXY_URL]: null, - [ConfigKey.SOURCE_PUSH]: null, + [ConfigKey.SOURCE_PROJECT_CONTENT]: null, [ConfigKey.SOURCE_INLINE]: null, [ConfigKey.PARAMS]: null, [ConfigKey.SCREENSHOTS]: null, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index 0579842d228f7..b8e4b48b38c5f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -64,7 +64,8 @@ export const normalizeProjectMonitor = ({ }, [ConfigKey.PROJECT_ID]: projectId || defaultFields[ConfigKey.PROJECT_ID], [ConfigKey.JOURNEY_ID]: monitor.id || defaultFields[ConfigKey.JOURNEY_ID], - [ConfigKey.SOURCE_PUSH]: monitor.content || defaultFields[ConfigKey.SOURCE_PUSH], + [ConfigKey.SOURCE_PROJECT_CONTENT]: + monitor.content || defaultFields[ConfigKey.SOURCE_PROJECT_CONTENT], [ConfigKey.LOCATIONS]: monitor.locations ?.map((key) => { return locations.find((location) => location.id === key); From f5707155d6b301e88bdba72038b799ff9b48cdac Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 20 May 2022 15:59:36 -0400 Subject: [PATCH 54/68] rename monitor source type --- .../plugins/synthetics/common/constants/monitor_defaults.ts | 2 +- .../synthetics/common/constants/monitor_management.ts | 2 +- .../runtime_types/monitor_management/monitor_types.ts | 2 +- .../components/fleet_package/common/formatters.ts | 2 +- .../components/fleet_package/common/normalizers.ts | 2 +- .../server/routes/monitor_cruds/monitor_validation.test.ts | 2 +- .../server/routes/telemetry/monitor_upgrade_sender.test.ts | 2 +- .../server/routes/telemetry/monitor_upgrade_sender.ts | 2 +- .../server/synthetics_service/formatters/common.ts | 3 ++- .../server/synthetics_service/normalizers/browser.test.ts | 6 +++--- .../server/synthetics_service/normalizers/browser.ts | 2 +- .../apis/uptime/rest/fixtures/browser_monitor.json | 2 +- .../apis/uptime/rest/fixtures/http_monitor.json | 2 +- .../apis/uptime/rest/fixtures/icmp_monitor.json | 2 +- .../apis/uptime/rest/fixtures/tcp_monitor.json | 2 +- 15 files changed, 18 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts index 2ce87e1cb96cb..d91342cdedbb0 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -42,7 +42,7 @@ export const DEFAULT_COMMON_FIELDS: CommonFields = { [ConfigKey.NAME]: '', [ConfigKey.LOCATIONS]: [], [ConfigKey.NAMESPACE]: DEFAULT_NAMESPACE_STRING, - [ConfigKey.SOURCE_TYPE]: SourceType.UI, + [ConfigKey.MONITOR_SOURCE_TYPE]: SourceType.UI, }; export const DEFAULT_BROWSER_ADVANCED_FIELDS: BrowserAdvancedFields = { diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index b212cfcb7e377..db010391839d5 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -12,7 +12,7 @@ export enum ConfigKey { ENABLED = 'enabled', HOSTS = 'hosts', IGNORE_HTTPS_ERRORS = 'ignore_https_errors', - SOURCE_TYPE = 'monitor.source', + MONITOR_SOURCE_TYPE = 'monitor.origin', JOURNEY_FILTERS_MATCH = 'filter_journeys.match', JOURNEY_FILTERS_TAGS = 'filter_journeys.tags', JOURNEY_ID = 'journey_id', diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index e50f7b0617d3b..2b343cfa68883 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -77,7 +77,7 @@ export const CommonFieldsCodec = t.intersection([ t.partial({ [ConfigKey.TIMEOUT]: t.union([t.string, t.null]), [ConfigKey.REVISION]: t.number, - [ConfigKey.SOURCE_TYPE]: SourceTypeCodec, + [ConfigKey.MONITOR_SOURCE_TYPE]: SourceTypeCodec, }), ]); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts index 5c7c49a678d72..dbe688039966b 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts @@ -25,7 +25,7 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.TIMEOUT]: (fields) => secondsToCronFormatter(fields[ConfigKey.TIMEOUT] || undefined), [ConfigKey.NAMESPACE]: null, [ConfigKey.REVISION]: null, - [ConfigKey.SOURCE_TYPE]: null, + [ConfigKey.MONITOR_SOURCE_TYPE]: null, }; export const arrayToJsonFormatter = (value: string[] = []) => diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts index 13f19c94d9b66..1d329a598f623 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts @@ -87,5 +87,5 @@ export const commonNormalizers: CommonNormalizerMap = { [ConfigKey.NAMESPACE]: (fields) => fields?.[ConfigKey.NAMESPACE]?.value ?? DEFAULT_NAMESPACE_STRING, [ConfigKey.REVISION]: getCommonNormalizer(ConfigKey.REVISION), - [ConfigKey.SOURCE_TYPE]: getCommonNormalizer(ConfigKey.SOURCE_TYPE), + [ConfigKey.MONITOR_SOURCE_TYPE]: getCommonNormalizer(ConfigKey.MONITOR_SOURCE_TYPE), }; diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts index 8f24719a6cefb..e862bec6e92cc 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts @@ -161,7 +161,7 @@ describe('validateMonitor', () => { testBrowserSimpleFields = { ...testZipUrlTLSFields, ...testCommonFields, - [ConfigKey.SOURCE_TYPE]: SourceType.PROJECT, + [ConfigKey.MONITOR_SOURCE_TYPE]: SourceType.PROJECT, [ConfigKey.JOURNEY_ID]: '', [ConfigKey.PROJECT_ID]: '', [ConfigKey.METADATA]: testMetaData, diff --git a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts index 50c5298aa4607..692f55d87297f 100644 --- a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts +++ b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.test.ts @@ -114,7 +114,7 @@ describe('monitor upgrade telemetry helpers', () => { }); it.each([ - [ConfigKey.SOURCE_TYPE, SourceType.PROJECT, 'project', false, false], + [ConfigKey.MONITOR_SOURCE_TYPE, SourceType.PROJECT, 'project', false, false], [ConfigKey.SOURCE_INLINE, 'test', 'recorder', true, true], [ConfigKey.SOURCE_INLINE, 'test', 'inline', false, true], [ConfigKey.SOURCE_ZIP_URL, 'test', 'zip', false, false], diff --git a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts index 9befa834ebad5..7bf84733da4a6 100644 --- a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts +++ b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts @@ -155,7 +155,7 @@ function getScriptType( return 'recorder'; case Boolean(isInlineScript): return 'inline'; - case attributes[ConfigKey.SOURCE_TYPE] === SourceType.PROJECT: + case attributes[ConfigKey.MONITOR_SOURCE_TYPE] === SourceType.PROJECT: return 'project'; default: return undefined; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts index 2bc323b25ff1f..bc9d178b1d31f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts @@ -26,7 +26,8 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.TIMEOUT]: (fields) => secondsToCronFormatter(fields[ConfigKey.TIMEOUT] || undefined), [ConfigKey.NAMESPACE]: null, [ConfigKey.REVISION]: null, - [ConfigKey.SOURCE_TYPE]: (fields) => fields[ConfigKey.SOURCE_TYPE] || SourceType.UI, + [ConfigKey.MONITOR_SOURCE_TYPE]: (fields) => + fields[ConfigKey.MONITOR_SOURCE_TYPE] || SourceType.UI, }; export const arrayFormatter = (value: string[] = []) => (value.length ? value : null); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index 956974e41b457..26c4d8de27717 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -106,7 +106,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-1', ignore_https_errors: true, - 'monitor.source': 'project', + 'monitor.origin': 'project', locations: [ { geo: { @@ -145,7 +145,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-2', ignore_https_errors: false, - 'monitor.source': 'project', + 'monitor.origin': 'project', locations: [ { geo: { @@ -195,7 +195,7 @@ describe('browser normalizers', () => { ...DEFAULT_FIELDS[DataStream.BROWSER], journey_id: 'test-id-3', ignore_https_errors: false, - 'monitor.source': 'project', + 'monitor.origin': 'project', locations: [ { geo: { diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index b8e4b48b38c5f..1880b89aa332f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -56,7 +56,7 @@ export const normalizeProjectMonitor = ({ const defaultFields = DEFAULT_FIELDS[DataStream.BROWSER]; const normalizedFields: NormalizedPublicFields = { [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, - [ConfigKey.SOURCE_TYPE]: SourceType.PROJECT, + [ConfigKey.MONITOR_SOURCE_TYPE]: SourceType.PROJECT, [ConfigKey.NAME]: monitor.name || '', [ConfigKey.SCHEDULE]: { number: `${monitor.schedule}`, diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json index c870f181ee13b..554f95ffd4587 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/browser_monitor.json @@ -43,5 +43,5 @@ "locations": [], "name": "Test HTTP Monitor 03", "namespace": "testnamespace", - "monitor.source": "ui" + "monitor.origin": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json index 995cafb7d2e14..a91630c9acee4 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json @@ -61,5 +61,5 @@ }], "namespace": "testnamespace", "revision": 1, - "monitor.source": "ui" + "monitor.origin": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json index bc1cfb49d4537..80286677c0697 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json @@ -33,5 +33,5 @@ ], "name": "Test HTTP Monitor 04", "namespace": "testnamespace", - "monitor.source": "ui" + "monitor.origin": "ui" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json index 622ee1a73692c..d5ac3b4721d48 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/tcp_monitor.json @@ -29,5 +29,5 @@ ], "name": "Test HTTP Monitor 04", "namespace": "testnamespace", - "monitor.source": "ui" + "monitor.origin": "ui" } From 76a3269a35084e902eb4b2b800d1910cd90ac04d Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Sun, 22 May 2022 17:09:39 -0400 Subject: [PATCH 55/68] add read only view --- .../browser/throttling_fields.tsx | 347 +++++++++--------- .../components/fleet_package/combo_box.tsx | 10 +- .../fleet_package/common/enabled.tsx | 4 +- .../contexts/policy_config_context.tsx | 7 + .../fleet_package/schedule_field.tsx | 5 +- .../action_bar/action_bar.tsx | 130 +++---- .../edit_monitor_config.tsx | 2 + .../monitor_config/locations.tsx | 10 +- .../monitor_config/monitor_fields.test.tsx | 62 +++- .../monitor_config/monitor_fields.tsx | 39 +- .../monitor_config/monitor_name_location.tsx | 17 +- .../read_only_browser_fields.tsx | 243 ++++++++++++ .../monitor_list/monitor_list.tsx | 11 +- .../lib/saved_objects/synthetics_monitor.ts | 2 +- 14 files changed, 617 insertions(+), 272 deletions(-) create mode 100644 x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/throttling_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/throttling_fields.tsx index ba023b6a1632f..850701b25f899 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/throttling_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/throttling_fields.tsx @@ -22,9 +22,10 @@ import { useBrowserAdvancedFieldsContext, usePolicyConfigContext } from '../cont import { Validation, ConfigKey, BandwidthLimitKey } from '../types'; interface Props { - validate: Validation; + validate?: Validation; minColumnWidth?: string; onFieldBlur?: (field: ConfigKey) => void; + readOnly?: boolean; } type ThrottlingConfigs = @@ -89,193 +90,205 @@ export const ThrottlingExceededMessage = ({ ); }; -export const ThrottlingFields = memo(({ validate, minColumnWidth, onFieldBlur }) => { - const { fields, setFields } = useBrowserAdvancedFieldsContext(); - const { runsOnService, throttling } = usePolicyConfigContext(); +export const ThrottlingFields = memo( + ({ validate, minColumnWidth, onFieldBlur, readOnly = false }) => { + const { fields, setFields } = useBrowserAdvancedFieldsContext(); + const { runsOnService, throttling } = usePolicyConfigContext(); - const maxDownload = throttling[BandwidthLimitKey.DOWNLOAD]; - const maxUpload = throttling[BandwidthLimitKey.UPLOAD]; + const maxDownload = throttling[BandwidthLimitKey.DOWNLOAD]; + const maxUpload = throttling[BandwidthLimitKey.UPLOAD]; - const handleInputChange = useCallback( - ({ value, configKey }: { value: unknown; configKey: ThrottlingConfigs }) => { - setFields((prevFields) => ({ ...prevFields, [configKey]: value })); - }, - [setFields] - ); + const handleInputChange = useCallback( + ({ value, configKey }: { value: unknown; configKey: ThrottlingConfigs }) => { + setFields((prevFields) => ({ ...prevFields, [configKey]: value })); + }, + [setFields] + ); - const exceedsDownloadLimits = - runsOnService && parseFloat(fields[ConfigKey.DOWNLOAD_SPEED]) > maxDownload; - const exceedsUploadLimits = - runsOnService && parseFloat(fields[ConfigKey.UPLOAD_SPEED]) > maxUpload; - const isThrottlingEnabled = fields[ConfigKey.IS_THROTTLING_ENABLED]; + const exceedsDownloadLimits = + runsOnService && parseFloat(fields[ConfigKey.DOWNLOAD_SPEED]) > maxDownload; + const exceedsUploadLimits = + runsOnService && parseFloat(fields[ConfigKey.UPLOAD_SPEED]) > maxUpload; + const isThrottlingEnabled = fields[ConfigKey.IS_THROTTLING_ENABLED]; - const throttlingInputs = isThrottlingEnabled ? ( - <> - - + + + } + labelAppend={} + isInvalid={ + (validate ? !!validate[ConfigKey.DOWNLOAD_SPEED]?.(fields) : false) || + exceedsDownloadLimits + } + error={ + exceedsDownloadLimits ? ( + + ) : ( + + ) + } + > + { + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.DOWNLOAD_SPEED, + }); + }} + onBlur={() => onFieldBlur?.(ConfigKey.DOWNLOAD_SPEED)} + data-test-subj="syntheticsBrowserDownloadSpeed" + append={ + + Mbps + + } + readOnly={readOnly} /> - } - labelAppend={} - isInvalid={!!validate[ConfigKey.DOWNLOAD_SPEED]?.(fields) || exceedsDownloadLimits} - error={ - exceedsDownloadLimits ? ( - - ) : ( + + - ) - } - > - { - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.DOWNLOAD_SPEED, - }); - }} - onBlur={() => onFieldBlur?.(ConfigKey.DOWNLOAD_SPEED)} - data-test-subj="syntheticsBrowserDownloadSpeed" - append={ - - Mbps - } - /> - - } + isInvalid={ + (validate ? !!validate[ConfigKey.DOWNLOAD_SPEED]?.(fields) : false) || + exceedsUploadLimits + } + error={ + exceedsUploadLimits ? ( + + ) : ( + + ) + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.UPLOAD_SPEED, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.UPLOAD_SPEED)} + data-test-subj="syntheticsBrowserUploadSpeed" + append={ + + Mbps + + } + readOnly={readOnly} /> - } - labelAppend={} - isInvalid={!!validate[ConfigKey.UPLOAD_SPEED]?.(fields) || exceedsUploadLimits} - error={ - exceedsUploadLimits ? ( - - ) : ( + + - ) - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.UPLOAD_SPEED, - }) } - onBlur={() => onFieldBlur?.(ConfigKey.UPLOAD_SPEED)} - data-test-subj="syntheticsBrowserUploadSpeed" - append={ - - Mbps - + labelAppend={} + isInvalid={validate ? !!validate[ConfigKey.DOWNLOAD_SPEED]?.(fields) : false} + error={ + } - /> - - + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.LATENCY, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.LATENCY)} + data-test-subj="syntheticsBrowserLatency" + append={ + + ms + + } + readOnly={readOnly} /> + + + ) : ( + <> + + + + ); + + return ( + + + } - labelAppend={} - isInvalid={!!validate[ConfigKey.LATENCY]?.(fields)} - error={ + description={ } > - + } onChange={(event) => handleInputChange({ - value: event.target.value, - configKey: ConfigKey.LATENCY, + value: event.target.checked, + configKey: ConfigKey.IS_THROTTLING_ENABLED, }) } - onBlur={() => onFieldBlur?.(ConfigKey.LATENCY)} - data-test-subj="syntheticsBrowserLatency" - append={ - - ms - - } - /> - - - ) : ( - <> - - - - ); - - return ( - - - - } - description={ - onFieldBlur?.(ConfigKey.IS_THROTTLING_ENABLED)} + disabled={readOnly} /> - } - > - - } - onChange={(event) => - handleInputChange({ - value: event.target.checked, - configKey: ConfigKey.IS_THROTTLING_ENABLED, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.IS_THROTTLING_ENABLED)} - /> - {isThrottlingEnabled && (exceedsDownloadLimits || exceedsUploadLimits) ? ( - <> - - - - ) : null} - {throttlingInputs} - - ); -}); + {isThrottlingEnabled && (exceedsDownloadLimits || exceedsUploadLimits) ? ( + <> + + + + ) : null} + {throttlingInputs} + + ); + } +); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/combo_box.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/combo_box.tsx index 16a31e8e5d623..553d94a9dc53a 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/combo_box.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/combo_box.tsx @@ -12,9 +12,16 @@ export interface Props { onChange: (value: string[]) => void; onBlur?: () => void; selectedOptions: string[]; + readOnly?: boolean; } -export const ComboBox = ({ onChange, onBlur, selectedOptions, ...props }: Props) => { +export const ComboBox = ({ + onChange, + onBlur, + selectedOptions, + readOnly = false, + ...props +}: Props) => { const [formattedSelectedOptions, setSelectedOptions] = useState< Array> >(selectedOptions.map((option) => ({ label: option, key: option }))); @@ -68,6 +75,7 @@ export const ComboBox = ({ onChange, onBlur, selectedOptions, ...props }: Props) onBlur={() => onBlur?.()} onSearchChange={onSearchChange} isInvalid={isInvalid} + isDisabled={readOnly} {...props} /> ); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/enabled.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/enabled.tsx index 1d76fe8a72e86..22d8116ceacce 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/enabled.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/enabled.tsx @@ -14,9 +14,10 @@ interface Props { fields: CommonFields; onChange: ({ value, configKey }: { value: boolean; configKey: ConfigKey }) => void; onBlur?: () => void; + readOnly?: boolean; } -export function Enabled({ fields, onChange, onBlur }: Props) { +export function Enabled({ fields, onChange, onBlur, readOnly }: Props) { return ( <> onBlur?.()} + disabled={readOnly} /> 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 a9cdc2c78d86d..1b019835bc16c 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 @@ -11,6 +11,7 @@ import { MONITOR_ADD_ROUTE } from '../../../../../common/constants'; import { DEFAULT_NAMESPACE_STRING } from '../../../../../common/constants/monitor_defaults'; import { ScheduleUnit, + SourceType, MonitorServiceLocations, ThrottlingOptions, DEFAULT_THROTTLING, @@ -41,6 +42,7 @@ interface IPolicyConfigContext { defaultNamespace?: string; namespace?: string; throttling: ThrottlingOptions; + sourceType?: SourceType; } export interface IPolicyConfigContextProvider { @@ -56,6 +58,7 @@ export interface IPolicyConfigContextProvider { isZipUrlSourceEnabled?: boolean; allowedScheduleUnits?: ScheduleUnit[]; throttling?: ThrottlingOptions; + sourceType?: SourceType; } export const initialMonitorTypeValue = DataStream.HTTP; @@ -93,6 +96,7 @@ export const defaultContext: IPolicyConfigContext = { allowedScheduleUnits: [ScheduleUnit.MINUTES, ScheduleUnit.SECONDS], defaultNamespace: DEFAULT_NAMESPACE_STRING, throttling: DEFAULT_THROTTLING, + sourceType: SourceType.UI, }; export const PolicyConfigContext = createContext(defaultContext); @@ -110,6 +114,7 @@ export function PolicyConfigContextProvider({ runsOnService = false, isZipUrlSourceEnabled = true, allowedScheduleUnits = [ScheduleUnit.MINUTES, ScheduleUnit.SECONDS], + sourceType, }: IPolicyConfigContextProvider) { const [monitorType, setMonitorType] = useState(defaultMonitorType); const [name, setName] = useState(defaultName); @@ -150,6 +155,7 @@ export function PolicyConfigContextProvider({ namespace, setNamespace, throttling, + sourceType, } as IPolicyConfigContext; }, [ monitorType, @@ -168,6 +174,7 @@ export function PolicyConfigContextProvider({ allowedScheduleUnits, namespace, throttling, + sourceType, ]); return ; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.tsx index e5d5d05a3cd77..70224b6df7047 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.tsx @@ -16,9 +16,10 @@ interface Props { onChange: (schedule: MonitorFields[ConfigKey.SCHEDULE]) => void; onBlur: () => void; unit: ScheduleUnit; + readOnly?: boolean; } -export const ScheduleField = ({ number, onChange, onBlur, unit }: Props) => { +export const ScheduleField = ({ number, onChange, onBlur, unit, readOnly = false }: Props) => { const { allowedScheduleUnits } = usePolicyConfigContext(); const options = !allowedScheduleUnits?.length ? allOptions @@ -55,6 +56,7 @@ export const ScheduleField = ({ number, onChange, onBlur, unit }: Props) => { onBlur(); }} + readOnly={readOnly} /> @@ -74,6 +76,7 @@ export const ScheduleField = ({ number, onChange, onBlur, unit }: Props) => { onChange({ number, unit: updatedUnit as ScheduleUnit }); }} onBlur={() => onBlur()} + disabled={readOnly} /> diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx index 80e614eb4d77f..c210a24ce54c3 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx @@ -25,7 +25,7 @@ import { MONITOR_MANAGEMENT_ROUTE } from '../../../../../common/constants'; import { UptimeSettingsContext } from '../../../contexts'; import { setMonitor } from '../../../state/api'; -import { SyntheticsMonitor } from '../../../../../common/runtime_types'; +import { ConfigKey, SyntheticsMonitor, SourceType } from '../../../../../common/runtime_types'; import { TestRun } from '../test_now_mode/test_now_mode'; import { monitorManagementListSelector } from '../../../state/selectors'; @@ -58,6 +58,7 @@ export const ActionBar = ({ const [isSaving, setIsSaving] = useState(false); const [isSuccessful, setIsSuccessful] = useState(false); const [isPopoverOpen, setIsPopoverOpen] = useState(undefined); + const isReadOnly = monitor[ConfigKey.MONITOR_SOURCE_TYPE] === SourceType.PROJECT; const { data, status } = useFetcher(() => { if (!isSaving || !isValid) { @@ -111,72 +112,73 @@ export const ActionBar = ({ return isSuccessful ? ( ) : ( - - - {!isValid && hasBeenSubmitted && VALIDATION_ERROR_LABEL} - + - - - - {DISCARD_LABEL} - - - - {onTestNow && ( + + {DISCARD_LABEL} + + + {!isReadOnly ? ( + + + + {!isValid && hasBeenSubmitted && VALIDATION_ERROR_LABEL} + + {onTestNow && ( + + {/* Popover is used instead of EuiTooltip until the resolution of https://github.com/elastic/eui/issues/5604 */} + onTestNow()} + onMouseEnter={() => { + setIsPopoverOpen(true); + }} + onMouseLeave={() => { + setIsPopoverOpen(false); + }} + > + {testRun ? RE_RUN_TEST_LABEL : RUN_TEST_LABEL} + + } + isOpen={isPopoverOpen} + > + +

{TEST_NOW_DESCRIPTION}

+
+
+
+ )} + - {/* Popover is used instead of EuiTooltip until the resolution of https://github.com/elastic/eui/issues/5604 */} - onTestNow()} - onMouseEnter={() => { - setIsPopoverOpen(true); - }} - onMouseLeave={() => { - setIsPopoverOpen(false); - }} - > - {testRun ? RE_RUN_TEST_LABEL : RUN_TEST_LABEL} - - } - isOpen={isPopoverOpen} + - -

{TEST_NOW_DESCRIPTION}

-
-
+ {monitorId ? UPDATE_MONITOR_LABEL : SAVE_MONITOR_LABEL} +
- )} - - - - {monitorId ? UPDATE_MONITOR_LABEL : SAVE_MONITOR_LABEL} - - -
-
+
+ + ) : null}
); }; @@ -187,7 +189,7 @@ const WarningText = euiStyled(EuiText)` `; const DISCARD_LABEL = i18n.translate('xpack.synthetics.monitorManagement.discardLabel', { - defaultMessage: 'Discard', + defaultMessage: 'Cancel', }); const SAVE_MONITOR_LABEL = i18n.translate('xpack.synthetics.monitorManagement.saveMonitorLabel', { 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 245f058c48d94..b04d548833ff9 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 @@ -13,6 +13,7 @@ import { TLSFields, DataStream, ScheduleUnit, + SourceType, ThrottlingOptions, } from '../../../../common/runtime_types'; import { SyntheticsProviders } from '../fleet_package/contexts'; @@ -85,6 +86,7 @@ export const EditMonitorConfig = ({ monitor, throttling }: Props) => { isZipUrlSourceEnabled: false, allowedScheduleUnits: [ScheduleUnit.MINUTES], runsOnService: true, + sourceType: monitor[ConfigKey.MONITOR_SOURCE_TYPE] || SourceType.UI, }} httpDefaultValues={fullDefaultConfig[DataStream.HTTP]} tcpDefaultValues={fullDefaultConfig[DataStream.TCP]} diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.tsx index 029503196b6a3..0671a82ccdd04 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.tsx @@ -17,9 +17,16 @@ interface Props { setLocations: React.Dispatch>; isInvalid: boolean; onBlur?: () => void; + readOnly?: boolean; } -export const ServiceLocations = ({ selectedLocations, setLocations, isInvalid, onBlur }: Props) => { +export const ServiceLocations = ({ + selectedLocations, + setLocations, + isInvalid, + onBlur, + readOnly = false, +}: Props) => { const [error, setError] = useState(null); const [checkboxIdToSelectedMap, setCheckboxIdToSelectedMap] = useState>( {} @@ -64,6 +71,7 @@ export const ServiceLocations = ({ selectedLocations, setLocations, isInvalid, o idToSelectedMap={checkboxIdToSelectedMap} onChange={(id) => onLocationChange(id)} onBlur={() => onBlur?.()} + disabled={readOnly} /> ); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx index b4e97ba724393..c92fc65ac2153 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx @@ -9,7 +9,13 @@ import { fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { ConfigKey, DataStream, HTTPFields } from '../../../../../common/runtime_types'; +import { + ConfigKey, + DataStream, + HTTPFields, + BrowserFields, + SourceType, +} from '../../../../../common/runtime_types'; import { render } from '../../../lib/helper/rtl_helpers'; import { BrowserContextProvider, @@ -19,26 +25,51 @@ import { TCPContextProvider, TLSFieldsContextProvider, } from '../../fleet_package/contexts'; -import { defaultConfig } from '../../fleet_package/synthetics_policy_create_extension'; +import { DEFAULT_FIELDS } from '../../../../../common/constants/monitor_defaults'; import { MonitorFields } from './monitor_fields'; -const defaultHTTPConfig = defaultConfig[DataStream.HTTP] as HTTPFields; +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 defaultHTTPConfig = DEFAULT_FIELDS[DataStream.HTTP] as HTTPFields; +const defaultBrowserConfig = DEFAULT_FIELDS[DataStream.BROWSER]; describe('', () => { const WrappedComponent = ({ isEditable = true, isFormSubmitted = false, defaultSimpleHttpFields = defaultHTTPConfig, + defaultBrowserFields = defaultBrowserConfig, + readOnly = false, }: { isEditable?: boolean; isFormSubmitted?: boolean; defaultSimpleHttpFields?: HTTPFields; + defaultBrowserFields?: BrowserFields; + readOnly?: boolean; }) => { return ( - + - + @@ -82,13 +113,22 @@ describe('', () => { expect(queryByText('URL is required')).not.toBeNull(); }); - it('does not show validation errors initially', async () => { - const httpInvalidValues = { ...defaultHTTPConfig, [ConfigKey.NAME]: '', [ConfigKey.URLS]: '' }; - const { queryByText } = render( - + it('is reradonly when source type is project', async () => { + const apmServiceName = 'service name'; + const browserFields = { + ...defaultBrowserConfig, + [ConfigKey.APM_SERVICE_NAME]: apmServiceName, + }; + const { getByText, getByTestId } = render( + ); - expect(queryByText('Monitor name is required')).toBeNull(); - expect(queryByText('URL is required')).toBeNull(); + expect(getByText('Read only')).toBeInTheDocument(); + const input = getByTestId('syntheticsAPMServiceName') as HTMLInputElement; + expect(input).toHaveValue(apmServiceName); }); }); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.tsx index eb109dd5d1063..2fe0afda08814 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.tsx @@ -7,18 +7,19 @@ import React, { useMemo, useState } from 'react'; import { EuiForm } from '@elastic/eui'; -import { ConfigKey, DataStream } from '../../../../../common/runtime_types'; +import { ConfigKey, DataStream, SourceType } from '../../../../../common/runtime_types'; import { usePolicyConfigContext } from '../../fleet_package/contexts'; import { CustomFields } from '../../fleet_package/custom_fields'; import { validate } from '../validation'; import { MonitorNameAndLocation } from './monitor_name_location'; import { MonitorManagementAdvancedFields } from './monitor_advanced_fields'; +import { ProjectBrowserReadonlyFields } from './read_only_browser_fields'; const MIN_COLUMN_WRAP_WIDTH = '360px'; export const MonitorFields = ({ isFormSubmitted = false }: { isFormSubmitted?: boolean }) => { - const { monitorType } = usePolicyConfigContext(); + const { monitorType, sourceType } = usePolicyConfigContext(); const [touchedFieldsHash, setTouchedFieldsHash] = useState>({}); @@ -41,21 +42,25 @@ export const MonitorFields = ({ isFormSubmitted = false }: { isFormSubmitted?: b return ( - - } - onFieldBlur={handleFieldBlur} - > - - + {sourceType === SourceType.PROJECT ? ( + + ) : ( + + } + onFieldBlur={handleFieldBlur} + > + + + )} ); }; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_name_location.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_name_location.tsx index 0f7206f65992f..f123d2e9800f8 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_name_location.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_name_location.tsx @@ -16,16 +16,19 @@ import { ServiceLocations } from './locations'; import { useMonitorName } from './use_monitor_name'; interface Props { - validate: Validation; + validate?: Validation; onFieldBlur?: (field: ConfigKey) => void; + readOnly?: boolean; } -export const MonitorNameAndLocation = ({ validate, onFieldBlur }: Props) => { +export const MonitorNameAndLocation = ({ validate, onFieldBlur, readOnly }: Props) => { const { name, setName, locations = [], setLocations } = usePolicyConfigContext(); - const isNameInvalid = !!validate[ConfigKey.NAME]?.({ [ConfigKey.NAME]: name }); - const isLocationsInvalid = !!validate[ConfigKey.LOCATIONS]?.({ - [ConfigKey.LOCATIONS]: locations, - }); + const isNameInvalid = validate ? !!validate[ConfigKey.NAME]?.({ [ConfigKey.NAME]: name }) : false; + const isLocationsInvalid = validate + ? !!validate[ConfigKey.LOCATIONS]?.({ + [ConfigKey.LOCATIONS]: locations, + }) + : false; const [localName, setLocalName] = useState(name); @@ -67,6 +70,7 @@ export const MonitorNameAndLocation = ({ validate, onFieldBlur }: Props) => { onChange={(event) => setLocalName(event.target.value)} onBlur={() => onFieldBlur?.(ConfigKey.NAME)} data-test-subj="monitorManagementMonitorName" + readOnly={readOnly} /> { selectedLocations={locations} isInvalid={isLocationsInvalid} onBlur={() => onFieldBlur?.(ConfigKey.LOCATIONS)} + readOnly={readOnly} /> ); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx new file mode 100644 index 0000000000000..020b3a1d1e169 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx @@ -0,0 +1,243 @@ +/* + * 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 from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiAccordion, + EuiCheckbox, + EuiCallOut, + EuiFormRow, + EuiFieldText, + EuiSpacer, +} from '@elastic/eui'; +import { ConfigKey } from '../../../../../common/runtime_types'; +import { + useBrowserSimpleFieldsContext, + useBrowserAdvancedFieldsContext, +} from '../../fleet_package/contexts'; +import { Enabled } from '../../fleet_package/common/enabled'; +import { ScheduleField } from '../../fleet_package/schedule_field'; +import { ComboBox } from '../../fleet_package/combo_box'; +import { MonitorNameAndLocation } from './monitor_name_location'; +import { ThrottlingFields } from '../../fleet_package/browser/throttling_fields'; +import { OptionalLabel } from '../../fleet_package/optional_label'; +import { DescribedFormGroupWithWrap } from '../../fleet_package/common/described_form_group_with_wrap'; + +const noop = () => {}; + +export const ProjectBrowserReadonlyFields = ({ minColumnWidth }: { minColumnWidth: string }) => { + const { fields } = useBrowserSimpleFieldsContext(); + const { fields: advancedFields } = useBrowserAdvancedFieldsContext(); + + return ( + <> + + } + iconType="document" + > +

+ +

+
+ + + + + } + description={ + + } + data-test-subj="monitorSettingsSection" + minColumnWidth={minColumnWidth} + > + + + + } + error={ + + } + > + + + + } + helpText={ + + } + labelAppend={} + > + + + + } + helpText={ + + } + labelAppend={} + > + + + + + + + + + + } + description={ + + } + minColumnWidth={minColumnWidth} + > + + + + + } + data-test-subj="syntheticsBrowserIgnoreHttpsErrors" + > + + } + onChange={noop} + /> + + + + } + helpText={ + + } + > + + + + } + helpText={ + + } + labelAppend={} + > + + + + + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx index 4b9374e991e6b..d75ab1bdf5879 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx @@ -25,6 +25,7 @@ import { ServiceLocations, EncryptedSyntheticsMonitorWithId, TCPSimpleFields, + BrowserFields, } from '../../../../../common/runtime_types'; import { UptimeSettingsContext } from '../../../contexts'; import { useBreakpoints } from '../../../../hooks/use_breakpoints'; @@ -119,8 +120,14 @@ export const MonitorManagementList = ({ defaultMessage: 'Monitor name', }), sortable: true, - render: (name: string, { id }: EncryptedSyntheticsMonitorWithId) => ( - {name} + render: (name: string, monitor: EncryptedSyntheticsMonitorWithId) => ( + + {name} + ), }, { diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts b/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts index 37b0bb05d2361..f77273235c804 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts @@ -50,7 +50,7 @@ export const syntheticsMonitor: SavedObjectsType = { project_id: { type: 'keyword', }, - 'monitor.source': { + 'monitor.origin': { type: 'keyword', }, }, From 913f44d47914ad0a54e8451e16af0fab4f3ef1fa Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Sun, 22 May 2022 17:56:49 -0400 Subject: [PATCH 56/68] update throttling config --- .../browser/throttling_fields.tsx | 5 ++-- .../synthetics_service/formatters/browser.ts | 25 +++++++++++-------- .../synthetics_service/formatters/common.ts | 2 +- .../formatters/format_configs.test.ts | 6 ++++- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/throttling_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/throttling_fields.tsx index 850701b25f899..31b4e6ee1fad0 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/throttling_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/throttling_fields.tsx @@ -166,8 +166,7 @@ export const ThrottlingFields = memo( } labelAppend={} isInvalid={ - (validate ? !!validate[ConfigKey.DOWNLOAD_SPEED]?.(fields) : false) || - exceedsUploadLimits + (validate ? !!validate[ConfigKey.UPLOAD_SPEED]?.(fields) : false) || exceedsUploadLimits } error={ exceedsUploadLimits ? ( @@ -208,7 +207,7 @@ export const ThrottlingFields = memo( /> } labelAppend={} - isInvalid={validate ? !!validate[ConfigKey.DOWNLOAD_SPEED]?.(fields) : false} + isInvalid={validate ? !!validate[ConfigKey.LATENCY]?.(fields) : false} error={ ; const throttlingFormatter: Formatter = (fields) => { if (!fields[ConfigKey.IS_THROTTLING_ENABLED]) return false; - const getThrottlingValue = (v: string | undefined, suffix: 'd' | 'u' | 'l') => - v !== '' && v !== undefined ? `${v}${suffix}` : null; - - return [ - getThrottlingValue(fields[ConfigKey.DOWNLOAD_SPEED], 'd'), - getThrottlingValue(fields[ConfigKey.UPLOAD_SPEED], 'u'), - getThrottlingValue(fields[ConfigKey.LATENCY], 'l'), - ] - .filter((v) => v !== null) - .join('/'); + return { + download: parseInt( + fields[ConfigKey.DOWNLOAD_SPEED] || DEFAULT_BROWSER_ADVANCED_FIELDS[ConfigKey.DOWNLOAD_SPEED], + 10 + ), + upload: parseInt( + fields[ConfigKey.UPLOAD_SPEED] || DEFAULT_BROWSER_ADVANCED_FIELDS[ConfigKey.UPLOAD_SPEED], + 10 + ), + latency: parseInt( + fields[ConfigKey.LATENCY] || DEFAULT_BROWSER_ADVANCED_FIELDS[ConfigKey.LATENCY], + 10 + ), + }; }; export const browserFormatters: BrowserFormatMap = { diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts index bc9d178b1d31f..63307f5cb80ab 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts @@ -7,7 +7,7 @@ import { CommonFields, ConfigKey, MonitorFields, SourceType } from '../../../common/runtime_types'; -export type FormattedValue = boolean | string | string[] | Record | null; +export type FormattedValue = boolean | string | string[] | Record | null; export type Formatter = null | ((fields: Partial) => FormattedValue); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.test.ts index c30d9af766b48..d0cc6266251e6 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.test.ts @@ -114,7 +114,11 @@ describe('formatMonitorConfig', () => { screenshots: 'on', 'source.inline.script': "step('Go to https://www.google.com/', async () => {\n await page.goto('https://www.google.com/');\n});", - throttling: '5d/3u/20l', + throttling: { + download: 5, + latency: 20, + upload: 3, + }, timeout: '16s', type: 'browser', synthetics_args: ['--hasTouch true'], From 8a8723fc63bd2b2eaecc5dd3fd368825390d0a0b Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Sun, 22 May 2022 22:34:42 -0400 Subject: [PATCH 57/68] disable enabled toggle --- .../monitor_list/monitor_list.tsx | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx index d75ab1bdf5879..27beefa1c7693 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx @@ -11,6 +11,7 @@ import { EuiLink, EuiPanel, EuiSpacer, + EuiToolTip, } from '@elastic/eui'; import { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types'; import { i18n } from '@kbn/i18n'; @@ -23,6 +24,7 @@ import { ICMPSimpleFields, Ping, ServiceLocations, + SourceType, EncryptedSyntheticsMonitorWithId, TCPSimpleFields, BrowserFields, @@ -181,12 +183,23 @@ export const MonitorManagementList = ({ defaultMessage: 'Enabled', }), render: (_enabled: boolean, monitor: EncryptedSyntheticsMonitorWithId) => ( - + + + ), }, { From 72f2a9216fab6f8cece4859747db52230cb80f2b Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 23 May 2022 12:10:19 -0400 Subject: [PATCH 58/68] adjust read only state --- .../monitor_config/read_only_browser_fields.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx index 020b3a1d1e169..94483a3391891 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx @@ -116,6 +116,7 @@ export const ProjectBrowserReadonlyFields = ({ minColumnWidth }: { minColumnWidt onChange={noop} onBlur={noop} data-test-subj="syntheticsAPMServiceName" + readOnly={true} /> } onChange={noop} + disabled={true} /> From 9af59f2b046ca8674e1f72dd9215f4f3c2d57ebd Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 23 May 2022 16:29:46 -0400 Subject: [PATCH 59/68] fix screenshots --- .../monitor_management/monitor_types_project.ts | 2 +- .../server/synthetics_service/normalizers/browser.test.ts | 6 +++--- .../server/synthetics_service/normalizers/browser.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts index 7157aa7eda848..324a17e08dd5e 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts @@ -24,7 +24,7 @@ export const ProjectBrowserMonitorCodec = t.intersection([ }), t.partial({ throttling: ProjectMonitorThrottlingConfigCodec, - screenshots: ScreenshotOptionCodec, + screenshot: ScreenshotOptionCodec, tags: t.array(t.string), ignoreHTTPSErrors: t.boolean, apmServiceName: t.string, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index 26c4d8de27717..ff28d42dff3af 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -42,7 +42,7 @@ describe('browser normalizers', () => { const monitors: ProjectBrowserMonitor[] = [ { id: 'test-id-1', - screenshots: ScreenshotOption.OFF, + screenshot: ScreenshotOption.OFF, name: 'test-name-1', content: 'test content 1', schedule: 3, @@ -58,7 +58,7 @@ describe('browser normalizers', () => { }, { id: 'test-id-2', - screenshots: ScreenshotOption.ON, + screenshot: ScreenshotOption.ON, name: 'test-name-2', content: 'test content 2', schedule: 10, @@ -76,7 +76,7 @@ describe('browser normalizers', () => { }, { id: 'test-id-3', - screenshots: ScreenshotOption.ON, + screenshot: ScreenshotOption.ON, name: 'test-name-3', content: 'test content 3', schedule: 10, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index 1880b89aa332f..92d598192844b 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -87,7 +87,7 @@ export const normalizeProjectMonitor = ({ monitor.apmServiceName || defaultFields[ConfigKey.APM_SERVICE_NAME], [ConfigKey.IGNORE_HTTPS_ERRORS]: monitor.ignoreHTTPSErrors || defaultFields[ConfigKey.IGNORE_HTTPS_ERRORS], - [ConfigKey.SCREENSHOTS]: monitor.screenshots || defaultFields[ConfigKey.SCREENSHOTS], + [ConfigKey.SCREENSHOTS]: monitor.screenshot || defaultFields[ConfigKey.SCREENSHOTS], [ConfigKey.TAGS]: monitor.tags || defaultFields[ConfigKey.TAGS], [ConfigKey.PLAYWRIGHT_OPTIONS]: Object.keys(monitor.playwrightOptions || {}).length ? JSON.stringify(monitor.playwrightOptions) From 017747aeed3baf769b4d251a42ed75eaefe76f1b Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 23 May 2022 16:37:19 -0400 Subject: [PATCH 60/68] remove unused fields from readonly --- .../monitor_config/monitor_fields.test.tsx | 8 +-- .../read_only_browser_fields.tsx | 70 ------------------- 2 files changed, 4 insertions(+), 74 deletions(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx index c92fc65ac2153..8898a02fb1d59 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx @@ -114,10 +114,10 @@ describe('', () => { }); it('is reradonly when source type is project', async () => { - const apmServiceName = 'service name'; + const name = 'monitor name'; const browserFields = { ...defaultBrowserConfig, - [ConfigKey.APM_SERVICE_NAME]: apmServiceName, + [ConfigKey.NAME]: name, }; const { getByText, getByTestId } = render( ', () => { ); expect(getByText('Read only')).toBeInTheDocument(); - const input = getByTestId('syntheticsAPMServiceName') as HTMLInputElement; - expect(input).toHaveValue(apmServiceName); + const input = getByTestId('monitorManagementMonitorName') as HTMLInputElement; + expect(input).toHaveValue(name); }); }); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx index 94483a3391891..82cd0d226712a 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx @@ -96,29 +96,6 @@ export const ProjectBrowserReadonlyFields = ({ minColumnWidth }: { minColumnWidt readOnly={true} /> - - } - helpText={ - - } - labelAppend={} - > - - - - - - } - data-test-subj="syntheticsBrowserIgnoreHttpsErrors" - > - - } - onChange={noop} - disabled={true} - /> - - - - } - helpText={ - - } - labelAppend={} - > - - From 378dc421ff1ffaa467e10a2c3b2f58f83efccee4 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 23 May 2022 16:40:31 -0400 Subject: [PATCH 61/68] adjust types --- .../server/routes/telemetry/monitor_upgrade_sender.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts index 7bf84733da4a6..081be18a54883 100644 --- a/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts +++ b/x-pack/plugins/synthetics/server/routes/telemetry/monitor_upgrade_sender.ts @@ -145,7 +145,7 @@ export function formatTelemetryDeleteEvent( function getScriptType( attributes: Partial, isInlineScript: boolean -): 'inline' | 'recorder' | 'zip' | 'project' | undefined { +): MonitorUpdateEvent['scriptType'] | undefined { switch (true) { case Boolean(attributes[ConfigKey.SOURCE_ZIP_URL]): return 'zip'; From 7477fe67eeb87244bd3975f3cf4868575fb47cdc Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 23 May 2022 20:43:56 +0000 Subject: [PATCH 62/68] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- .../monitor_config/read_only_browser_fields.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx index 82cd0d226712a..6614b4d1ce4aa 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/read_only_browser_fields.tsx @@ -7,14 +7,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import { - EuiAccordion, - EuiCheckbox, - EuiCallOut, - EuiFormRow, - EuiFieldText, - EuiSpacer, -} from '@elastic/eui'; +import { EuiAccordion, EuiCallOut, EuiFormRow, EuiFieldText, EuiSpacer } from '@elastic/eui'; import { ConfigKey } from '../../../../../common/runtime_types'; import { useBrowserSimpleFieldsContext, From b026d9e84b4a01a33bc32575451c35dd56d3209b Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 23 May 2022 22:07:41 -0400 Subject: [PATCH 63/68] adjust monitor details logic for falling back to saved objects --- .../lib/saved_objects/synthetics_monitor.ts | 3 +++ .../legacy_uptime/routes/monitors/monitor_status.ts | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts b/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts index f77273235c804..e9a2bc1710860 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/lib/saved_objects/synthetics_monitor.ts @@ -53,6 +53,9 @@ export const syntheticsMonitor: SavedObjectsType = { 'monitor.origin': { type: 'keyword', }, + custom_heartbeat_id: { + type: 'keyword', + }, }, }, management: { diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/routes/monitors/monitor_status.ts b/x-pack/plugins/synthetics/server/legacy_uptime/routes/monitors/monitor_status.ts index 713a7f8123153..772a85c4d76bc 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/routes/monitors/monitor_status.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/routes/monitors/monitor_status.ts @@ -10,6 +10,7 @@ import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; import { API_URLS } from '../../../../common/constants'; import { ConfigKey, MonitorFields } from '../../../../common/runtime_types'; +import { syntheticsMonitorType } from '../../../../common/types/saved_objects'; export const createGetStatusBarRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', @@ -41,10 +42,13 @@ export const createGetStatusBarRoute: UMRestApiRouteFactory = (libs: UMServerLib } try { - const monitorSavedObject = await libs.requests.getSyntheticsMonitor({ - monitorId, - encryptedSavedObjectsClient, - savedObjectsClient, + const { + saved_objects: [monitorSavedObject], + } = await savedObjectsClient.find({ + type: syntheticsMonitorType, + perPage: 1, + page: 1, + filter: `${syntheticsMonitorType}.id: "${syntheticsMonitorType}:${monitorId}" OR ${syntheticsMonitorType}.attributes.${ConfigKey.CUSTOM_HEARTBEAT_ID}: "${monitorId}"`, }); if (!monitorSavedObject) { From e832b56dde6fbf9f487c735fb8f99a2d7c5aa775 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 23 May 2022 22:11:37 -0400 Subject: [PATCH 64/68] remove journey id and project id validation --- .../monitor_cruds/monitor_validation.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts index b395e83acc9ba..92a8f8cd81d82 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts @@ -91,29 +91,10 @@ export function validateProjectMonitor( details: string; payload: object; } { - const isValidId = new RegExp(/^[0-9A-Za-z-._~]+$/); - const isJourneyIdValid = isValidId.test(monitorFields.id); - const isProjectIdValid = isValidId.test(projectId); - const projectIdError = !isProjectIdValid - ? `Project id is invalid. Project id: ${projectId}. ` - : ''; - const journeyIdError = !isJourneyIdValid - ? `Journey id is invalid. Journey id: ${monitorFields.id}.` - : ''; const locationsError = monitorFields.locations && monitorFields.locations.length === 0 ? 'Invalid value "[]" supplied to field "locations"' : ''; - - if (!isProjectIdValid || !isJourneyIdValid) { - return { - valid: false, - reason: - 'Failed to save or update monitor. Journey id or Project id is not valid. Id must match pattern ^[0-9A-Za-z-._~]$', - details: `${projectIdError}${journeyIdError}`, - payload: monitorFields, - }; - } // Cast it to ICMPCodec to satisfy typing. During runtime, correct codec will be used to decode. const decodedMonitor = ProjectBrowserMonitorCodec.decode(monitorFields); From 5cf6ffc2865de9934aa566c2cb8b59624197a0de Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 23 May 2022 23:00:07 -0400 Subject: [PATCH 65/68] adjust tests --- .../monitor_config/monitor_fields.test.tsx | 2 - .../routes/monitors/monitor_status.ts | 1 - .../apis/uptime/rest/add_monitor_project.ts | 100 ------------------ 3 files changed, 103 deletions(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx index 8898a02fb1d59..a03454e3bfd34 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx @@ -128,7 +128,5 @@ describe('', () => { ); expect(getByText('Read only')).toBeInTheDocument(); - const input = getByTestId('monitorManagementMonitorName') as HTMLInputElement; - expect(input).toHaveValue(name); }); }); diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/routes/monitors/monitor_status.ts b/x-pack/plugins/synthetics/server/legacy_uptime/routes/monitors/monitor_status.ts index 772a85c4d76bc..2bf898bf309d4 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/routes/monitors/monitor_status.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/routes/monitors/monitor_status.ts @@ -24,7 +24,6 @@ export const createGetStatusBarRoute: UMRestApiRouteFactory = (libs: UMServerLib }, handler: async ({ uptimeEsClient, request, server, savedObjectsClient }): Promise => { const { monitorId, dateStart, dateEnd } = request.query; - const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); const latestMonitor = await libs.requests.getLatestMonitor({ uptimeEsClient, diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts index b9c8e3ba10cdb..8daccb85b7e6d 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts @@ -414,106 +414,6 @@ export default function ({ getService }: FtrProviderContext) { } }); - it('project monitors - validates project id', async () => { - try { - const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) - .set('kbn-xsrf', 'true') - .send({ ...projectMonitors, project: 'not a valid/ id$?' }); - - expect(apiResponse.body.updatedMonitors).eql([]); - expect(apiResponse.body.failedMonitors).eql([ - { - details: 'Project id is invalid. Project id: not a valid/ id$?. ', - id: projectMonitors.monitors[0].id, - payload: { - content: - 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', - filter: { - match: 'check if title is present', - }, - id: projectMonitors.monitors[0].id, - locations: ['us-east4-a'], - name: 'check if title is present', - params: {}, - playwrightOptions: { - chromiumSandbox: false, - headless: true, - }, - schedule: 10, - tags: [], - throttling: { - download: 5, - latency: 20, - upload: 3, - }, - }, - reason: - 'Failed to save or update monitor. Journey id or Project id is not valid. Id must match pattern ^[0-9A-Za-z-._~]$', - }, - ]); - expect(apiResponse.body.createdMonitors).eql([]); - } finally { - await Promise.all([ - projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); - }), - ]); - } - }); - - it('project monitors - validates journey id', async () => { - const id = 'not a valid/ id?&'; - try { - const apiResponse = await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) - .set('kbn-xsrf', 'true') - .send({ - ...projectMonitors, - monitors: [{ ...projectMonitors.monitors[0], id }], - }); - - expect(apiResponse.body.updatedMonitors).eql([]); - expect(apiResponse.body.failedMonitors).eql([ - { - details: `Journey id is invalid. Journey id: ${id}.`, - id, - payload: { - content: - 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', - filter: { - match: 'check if title is present', - }, - id, - locations: ['us-east4-a'], - name: 'check if title is present', - params: {}, - playwrightOptions: { - chromiumSandbox: false, - headless: true, - }, - schedule: 10, - tags: [], - throttling: { - download: 5, - latency: 20, - upload: 3, - }, - }, - reason: - 'Failed to save or update monitor. Journey id or Project id is not valid. Id must match pattern ^[0-9A-Za-z-._~]$', - }, - ]); - expect(apiResponse.body.createdMonitors).eql([]); - } finally { - await Promise.all([ - projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); - }), - ]); - } - }); - it('project monitors - validates monitor type', async () => { try { const apiResponse = await supertest From deed9115e5520a3dd0be4ad9603dd6e73819d926 Mon Sep 17 00:00:00 2001 From: shahzad31 Date: Tue, 24 May 2022 12:20:22 +0200 Subject: [PATCH 66/68] lint fix --- .../monitor_management/monitor_config/monitor_fields.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx index a03454e3bfd34..5cd82233a5890 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx @@ -119,7 +119,7 @@ describe('', () => { ...defaultBrowserConfig, [ConfigKey.NAME]: name, }; - const { getByText, getByTestId } = render( + const { getByText } = render( Date: Tue, 24 May 2022 09:19:42 -0400 Subject: [PATCH 67/68] update test --- .../monitor_management/monitor_config/monitor_fields.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx index a03454e3bfd34..5cd82233a5890 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx @@ -119,7 +119,7 @@ describe('', () => { ...defaultBrowserConfig, [ConfigKey.NAME]: name, }; - const { getByText, getByTestId } = render( + const { getByText } = render( Date: Tue, 24 May 2022 10:19:59 -0400 Subject: [PATCH 68/68] adjust types --- .../server/synthetics_service/normalizers/browser.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts index ff28d42dff3af..d5583384a6d5c 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts @@ -9,6 +9,7 @@ import { DataStream, ScreenshotOption, Locations, + LocationStatus, ProjectBrowserMonitor, } from '../../../common/runtime_types'; import { DEFAULT_FIELDS } from '../../../common/constants/monitor_defaults'; @@ -30,6 +31,7 @@ describe('browser normalizers', () => { geo: { lat: 33.333, lon: 73.333 }, url: 'test-url', isServiceManaged: true, + status: LocationStatus.GA, }, { id: 'us_east', @@ -37,6 +39,7 @@ describe('browser normalizers', () => { geo: { lat: 33.333, lon: 73.333 }, url: 'test-url', isServiceManaged: true, + status: LocationStatus.GA, }, ]; const monitors: ProjectBrowserMonitor[] = [ @@ -117,6 +120,7 @@ describe('browser normalizers', () => { isServiceManaged: true, label: 'Test Location', url: 'test-url', + status: 'ga', }, ], name: 'test-name-1', @@ -156,6 +160,7 @@ describe('browser normalizers', () => { isServiceManaged: true, label: 'Test Location', url: 'test-url', + status: 'ga', }, { geo: { @@ -166,6 +171,7 @@ describe('browser normalizers', () => { isServiceManaged: true, label: 'Test Location', url: 'test-url', + status: 'ga', }, ], name: 'test-name-2', @@ -206,6 +212,7 @@ describe('browser normalizers', () => { isServiceManaged: true, label: 'Test Location', url: 'test-url', + status: 'ga', }, { geo: { @@ -216,6 +223,7 @@ describe('browser normalizers', () => { isServiceManaged: true, label: 'Test Location', url: 'test-url', + status: 'ga', }, ], name: 'test-name-3',