From 94c7acdc060609713bca2bee100e710fb78f5af5 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 2 May 2023 14:28:41 -0400 Subject: [PATCH] synthetics - adjust monitor status rule location logic --- .../status_rule/status_rule_executor.test.ts | 100 +++++++++++++++++- .../status_rule/status_rule_executor.ts | 11 +- 2 files changed, 107 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.test.ts b/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.test.ts index 28d7018448374..bb7cd4317b494 100644 --- a/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.test.ts +++ b/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.test.ts @@ -4,22 +4,37 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -import { StatusRuleExecutor } from './status_rule_executor'; +import moment from 'moment'; import { loggerMock } from '@kbn/logging-mocks'; import { savedObjectsClientMock } from '@kbn/core-saved-objects-api-server-mocks'; +import { StatusRuleExecutor } from './status_rule_executor'; import { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; import { mockEncryptedSO } from '../../synthetics_service/utils/mocks'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import { SyntheticsMonitorClient } from '../../synthetics_service/synthetics_monitor/synthetics_monitor_client'; import { SyntheticsService } from '../../synthetics_service/synthetics_service'; -import moment from 'moment'; import * as monitorUtils from '../../saved_objects/synthetics_monitor/get_all_monitors'; +import * as locationsUtils from '../../synthetics_service/get_all_locations'; +import type { PublicLocation } from '../../../common/runtime_types'; describe('StatusRuleExecutor', () => { const mockEsClient = elasticsearchClientMock.createElasticsearchClient(); const logger = loggerMock.create(); const soClient = savedObjectsClientMock.create(); + jest.spyOn(locationsUtils, 'getAllLocations').mockResolvedValue({ + // @ts-ignore + publicLocations: [ + { + id: 'us_central_qa', + label: 'US Central QA', + }, + { + id: 'us_central_dev', + label: 'US Central DEV', + }, + ] as unknown as PublicLocation, + privateLocations: [], + }); const serverMock: UptimeServerSetup = { logger, @@ -64,6 +79,7 @@ describe('StatusRuleExecutor', () => { soClient, }); }); + it('marks deleted configs as expected', async () => { jest.spyOn(monitorUtils, 'getAllMonitors').mockResolvedValue(testMonitors); const statusRule = new StatusRuleExecutor( @@ -127,6 +143,84 @@ describe('StatusRuleExecutor', () => { }, }); }); + + it('does not mark deleted config when monitor does not contain location label', async () => { + jest.spyOn(monitorUtils, 'getAllMonitors').mockResolvedValue([ + { + ...testMonitors[0], + attributes: { + ...testMonitors[0].attributes, + locations: [ + { + geo: { lon: -95.86, lat: 41.25 }, + isServiceManaged: true, + id: 'us_central_qa', + }, + ], + }, + }, + ]); + const statusRule = new StatusRuleExecutor( + moment().toDate(), + {}, + soClient, + mockEsClient, + serverMock, + monitorClient + ); + + const { downConfigs } = await statusRule.getDownChecks({}); + + expect(downConfigs).toEqual({}); + + const staleDownConfigs = await statusRule.markDeletedConfigs({ + id1: { + location: 'us-east-1', + configId: 'id1', + status: 'down', + timestamp: '2021-06-01T00:00:00.000Z', + monitorQueryId: 'test', + ping: {} as any, + }, + '2548dab3-4752-4b4d-89a2-ae3402b6fb04-us_central_dev': { + location: 'US Central DEV', + configId: '2548dab3-4752-4b4d-89a2-ae3402b6fb04', + status: 'down', + timestamp: '2021-06-01T00:00:00.000Z', + monitorQueryId: 'test', + ping: {} as any, + }, + '2548dab3-4752-4b4d-89a2-ae3402b6fb04-us_central_qa': { + location: 'US Central QA', + configId: '2548dab3-4752-4b4d-89a2-ae3402b6fb04', + status: 'down', + timestamp: '2021-06-01T00:00:00.000Z', + monitorQueryId: 'test', + ping: {} as any, + }, + }); + + expect(staleDownConfigs).toEqual({ + id1: { + configId: 'id1', + isDeleted: true, + location: 'us-east-1', + monitorQueryId: 'test', + ping: {}, + status: 'down', + timestamp: '2021-06-01T00:00:00.000Z', + }, + '2548dab3-4752-4b4d-89a2-ae3402b6fb04-us_central_dev': { + configId: '2548dab3-4752-4b4d-89a2-ae3402b6fb04', + isLocationRemoved: true, + location: 'US Central DEV', + monitorQueryId: 'test', + ping: {}, + status: 'down', + timestamp: '2021-06-01T00:00:00.000Z', + }, + }); + }); }); const testMonitors = [ diff --git a/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.ts b/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.ts index 3b73245977dff..b2b3c8094ee6c 100644 --- a/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.ts +++ b/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.ts @@ -49,6 +49,7 @@ export class StatusRuleExecutor { monitors: Array> = []; public locationIdNameMap: Record = {}; + public locationNameIdMap: Record = {}; constructor( previousStartedAt: Date | null, @@ -75,10 +76,12 @@ export class StatusRuleExecutor { publicLocations.forEach((loc) => { this.locationIdNameMap[loc.label] = loc.id; + this.locationNameIdMap[loc.id] = loc.label; }); privateLocations.forEach((loc) => { this.locationIdNameMap[loc.label] = loc.id; + this.locationIdNameMap[loc.id] = loc.label; }); } @@ -195,7 +198,13 @@ export class StatusRuleExecutor { delete downConfigs[locPlusId]; } else { const { locations } = monitor.attributes; - if (!locations.some((l) => l.label === downConfig.location)) { + if ( + !locations.some( + (l) => + l.label === downConfig.location || + this.locationNameIdMap[l.id] === downConfig.location + ) + ) { staleDownConfigs[locPlusId] = { ...downConfig, isLocationRemoved: true }; delete downConfigs[locPlusId]; }