Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
SYNTHETICS_STATUS_RULE,
SYNTHETICS_TLS_RULE,
} from '../../../common/constants/synthetics_alerts';
import { DefaultAlertService } from './default_alert_service';
import { DefaultRuleService } from './default_alert_service';
import { DYNAMIC_SETTINGS_DEFAULTS } from '../../constants/settings';

describe('DefaultAlertService', () => {
Expand All @@ -24,7 +24,7 @@ describe('DefaultAlertService', () => {
const soResponse = { attributes: { ...expectedSettings } };
it('returns settings if already set', async () => {
const soClient = { get: jest.fn() } as any;
const service = new DefaultAlertService({} as any, {} as any, soClient);
const service = new DefaultRuleService({} as any, {} as any, soClient);
service.settings = expectedSettings;
const settings = await service.getSettings();
expect(settings).toEqual(expectedSettings);
Expand All @@ -33,7 +33,7 @@ describe('DefaultAlertService', () => {

it('fetches settings if not set', async () => {
const soClient = { get: jest.fn() } as any;
const service = new DefaultAlertService({} as any, {} as any, soClient);
const service = new DefaultRuleService({} as any, {} as any, soClient);
soClient.get.mockResolvedValueOnce(soResponse);
const settings = await service.getSettings();
expect(settings).toEqual({
Expand All @@ -51,7 +51,7 @@ describe('DefaultAlertService', () => {

it('sets up status and tls rules', async () => {
const soClient = { get: jest.fn() } as any;
const service = new DefaultAlertService({} as any, {} as any, soClient);
const service = new DefaultRuleService({} as any, {} as any, soClient);
service.getSettings = jest.fn().mockResolvedValue({
certAgeThreshold: 50,
certExpirationThreshold: 10,
Expand All @@ -66,7 +66,7 @@ describe('DefaultAlertService', () => {
service.setupTlsRule = setupTlsRule;
setupStatusRule.mockResolvedValueOnce({ status: 'fulfilled', value: {} });
setupTlsRule.mockResolvedValueOnce({ status: 'fulfilled', value: {} });
const result = await service.setupDefaultAlerts();
const result = await service.setupDefaultRules();
expect(setupStatusRule).toHaveBeenCalledTimes(1);
expect(setupTlsRule).toHaveBeenCalledTimes(1);
expect(result).toEqual({
Expand All @@ -76,7 +76,7 @@ describe('DefaultAlertService', () => {
});
it('returns null rules if value is falsy', async () => {
const soClient = { get: jest.fn() } as any;
const service = new DefaultAlertService({} as any, {} as any, soClient);
const service = new DefaultRuleService({} as any, {} as any, soClient);
service.getSettings = jest.fn().mockResolvedValue({
certAgeThreshold: 50,
certExpirationThreshold: 10,
Expand All @@ -91,7 +91,7 @@ describe('DefaultAlertService', () => {
service.setupTlsRule = setupTlsRule;
setupStatusRule.mockResolvedValueOnce(undefined);
setupTlsRule.mockResolvedValueOnce(undefined);
const result = await service.setupDefaultAlerts();
const result = await service.setupDefaultRules();
expect(setupStatusRule).toHaveBeenCalledTimes(1);
expect(setupTlsRule).toHaveBeenCalledTimes(1);
expect(result).toEqual({
Expand All @@ -106,22 +106,22 @@ describe('DefaultAlertService', () => {
const server = {
alerting: { getConfig: () => ({ minimumScheduleInterval: { value: '30s' } }) },
} as any;
const service = new DefaultAlertService({} as any, server, {} as any);
const service = new DefaultRuleService({} as any, server, {} as any);
expect(service.getMinimumRuleInterval()).toBe('1m');
});

it('returns minimum interval if greater than 1m', () => {
const server = {
alerting: { getConfig: () => ({ minimumScheduleInterval: { value: '5m' } }) },
} as any;
const service = new DefaultAlertService({} as any, server, {} as any);
const service = new DefaultRuleService({} as any, server, {} as any);
expect(service.getMinimumRuleInterval()).toBe('5m');
});
});

describe('setupStatusRule', () => {
it('creates status rule if enabled', async () => {
const service = new DefaultAlertService({} as any, {} as any, {} as any);
const service = new DefaultRuleService({} as any, {} as any, {} as any);
service.getMinimumRuleInterval = jest.fn().mockReturnValue('1m');
service.createDefaultRuleIfNotExist = jest.fn();
service.settings = { defaultStatusRuleEnabled: true } as any;
Expand All @@ -137,7 +137,7 @@ describe('DefaultAlertService', () => {
});

it('does not create status rule if disabled', async () => {
const service = new DefaultAlertService({} as any, {} as any, {} as any);
const service = new DefaultRuleService({} as any, {} as any, {} as any);
service.getMinimumRuleInterval = jest.fn().mockReturnValue('1m');
service.createDefaultRuleIfNotExist = jest.fn();
service.settings = { defaultStatusRuleEnabled: false } as any;
Expand All @@ -149,7 +149,7 @@ describe('DefaultAlertService', () => {

describe('setupTlsRule', () => {
it('creates tls rule if enabled', async () => {
const service = new DefaultAlertService({} as any, {} as any, {} as any);
const service = new DefaultRuleService({} as any, {} as any, {} as any);
service.getMinimumRuleInterval = jest.fn().mockReturnValue('1m');
service.createDefaultRuleIfNotExist = jest.fn();
service.settings = { defaultTlsRuleEnabled: true } as any;
Expand All @@ -165,7 +165,7 @@ describe('DefaultAlertService', () => {
});

it('does not create tls rule if disabled', async () => {
const service = new DefaultAlertService({} as any, {} as any, {} as any);
const service = new DefaultRuleService({} as any, {} as any, {} as any);
service.getMinimumRuleInterval = jest.fn().mockReturnValue('1m');
service.createDefaultRuleIfNotExist = jest.fn();
service.settings = { defaultTLSRuleEnabled: false } as any;
Expand Down Expand Up @@ -209,7 +209,7 @@ describe('DefaultAlertService', () => {
describe('getExistingAlert', () => {
it('returns rule if exists', async () => {
const { getRulesClient, mockRule } = setUpExistingRules();
const service = new DefaultAlertService(
const service = new DefaultRuleService(
{ alerting: { getRulesClient } } as any,
{} as any,
{} as any
Expand All @@ -222,7 +222,7 @@ describe('DefaultAlertService', () => {
const find = jest.fn().mockResolvedValue({ data: [] });
const getRulesClient = jest.fn();
getRulesClient.mockReturnValue({ find });
const service = new DefaultAlertService(
const service = new DefaultRuleService(
{ alerting: { getRulesClient } } as any,
{} as any,
{} as any
Expand All @@ -234,7 +234,7 @@ describe('DefaultAlertService', () => {
describe('createDefaultAlertIfNotExist', () => {
it('returns rule if exists', async () => {
const { getRulesClient, mockRule } = setUpExistingRules();
const service = new DefaultAlertService(
const service = new DefaultRuleService(
{ alerting: { getRulesClient } } as any,
{} as any,
{} as any
Expand Down Expand Up @@ -265,7 +265,7 @@ describe('DefaultAlertService', () => {
});
const getRulesClient = jest.fn();
getRulesClient.mockReturnValue({ find, create });
const service = new DefaultAlertService(
const service = new DefaultRuleService(
{ actions: { getActionsClient }, alerting: { getRulesClient } } as any,
{} as any,
{} as any
Expand Down Expand Up @@ -330,7 +330,7 @@ describe('DefaultAlertService', () => {
schedule: { interval: '1m' },
params: { param: 'value' },
});
const service = new DefaultAlertService(context as any, server as any, {} as any);
const service = new DefaultRuleService(context as any, server as any, {} as any);
service.settings = { defaultConnectors: ['slack', 'email'] } as any;
const result = await service.updateStatusRule(true);
expect(result).toEqual({
Expand Down Expand Up @@ -364,7 +364,7 @@ describe('DefaultAlertService', () => {
} as any;
const bulkDeleteRules = jest.fn();
const { getRulesClient } = setUpExistingRules(undefined, { bulkDeleteRules });
const service = new DefaultAlertService(
const service = new DefaultRuleService(
{ alerting: { getRulesClient } } as any,
server as any,
{} as any
Expand All @@ -381,7 +381,7 @@ describe('DefaultAlertService', () => {
describe('updateTlsRule', () => {
it('updates the rule if it is enabled', async () => {
const { context, server } = setUpUpdateTest();
const service = new DefaultAlertService(context as any, server as any, {} as any);
const service = new DefaultRuleService(context as any, server as any, {} as any);
service.settings = { defaultConnectors: ['slack', 'email'] } as any;
const result = await service.updateTlsRule(true);
expect(result).toEqual({
Expand All @@ -397,7 +397,7 @@ describe('DefaultAlertService', () => {

it('creates the rule if it does not exist', async () => {
const { context, server } = setUpUpdateTest();
const service = new DefaultAlertService(context as any, server as any, {} as any);
const service = new DefaultRuleService(context as any, server as any, {} as any);
service.settings = { defaultConnectors: ['slack', 'email'] } as any;
const getExistingAlertMock = jest.fn().mockResolvedValue(undefined);
service.getExistingAlert = getExistingAlertMock;
Expand All @@ -423,7 +423,7 @@ describe('DefaultAlertService', () => {
} as any;
const bulkDeleteRules = jest.fn();
const { getRulesClient } = setUpExistingRules(undefined, { bulkDeleteRules });
const service = new DefaultAlertService(
const service = new DefaultRuleService(
{ alerting: { getRulesClient } } as any,
server as any,
{} as any
Expand All @@ -445,7 +445,7 @@ describe('DefaultAlertService', () => {
getActionsClient.mockReturnValue({
getAll,
});
const service = new DefaultAlertService(
const service = new DefaultRuleService(
{ actions: { getActionsClient } } as any,
{} as any,
{ get: jest.fn() } as any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { parseDuration } from '@kbn/alerting-plugin/server';
import type { FindActionResult } from '@kbn/actions-plugin/server';
import { isEmpty } from 'lodash';
import { getSyntheticsDynamicSettings } from '../../saved_objects/synthetics_settings';
import type { DynamicSettingsAttributes } from '../../runtime_types/settings';
import { populateAlertActions } from '../../../common/rules/alert_actions';
Expand All @@ -22,7 +23,7 @@ import {
SYNTHETICS_TLS_RULE,
} from '../../../common/constants/synthetics_alerts';
import type { DefaultRuleType } from '../../../common/types/default_alerts';
export class DefaultAlertService {
export class DefaultRuleService {
context: UptimeRequestHandlerContext;
soClient: SavedObjectsClientContract;
server: SyntheticsServerSetup;
Expand All @@ -45,8 +46,15 @@ export class DefaultAlertService {
return this.settings;
}

async setupDefaultAlerts() {
async setupDefaultRules() {
this.settings = await this.getSettings();
if (isEmpty(this.settings?.defaultConnectors)) {
this.server.logger.debug(`Default connectors are not set. Skipping default rule setup.`);
return {
statusRule: null,
tlsRule: null,
};
}

const [statusRule, tlsRule] = await Promise.allSettled([
this.setupStatusRule(),
Expand Down Expand Up @@ -152,7 +160,7 @@ export class DefaultAlertService {
async updateStatusRule(enabled?: boolean) {
const minimumRuleInterval = this.getMinimumRuleInterval();
if (enabled) {
return this.upsertDefaultAlert(
return this.upsertDefaultRule(
SYNTHETICS_STATUS_RULE,
`Synthetics status internal rule`,
minimumRuleInterval
Expand All @@ -168,7 +176,7 @@ export class DefaultAlertService {
async updateTlsRule(enabled?: boolean) {
const minimumRuleInterval = this.getMinimumRuleInterval();
if (enabled) {
return this.upsertDefaultAlert(
return this.upsertDefaultRule(
SYNTHETICS_TLS_RULE,
`Synthetics internal TLS rule`,
minimumRuleInterval
Expand All @@ -181,7 +189,7 @@ export class DefaultAlertService {
}
}

async upsertDefaultAlert(ruleType: DefaultRuleType, name: string, interval: string) {
async upsertDefaultRule(ruleType: DefaultRuleType, name: string, interval: string) {
const rulesClient = await (await this.context.alerting)?.getRulesClient();

const alert = await this.getExistingAlert(ruleType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { DefaultAlertService } from './default_alert_service';
import { DefaultRuleService } from './default_alert_service';
import type { SyntheticsRestApiRouteFactory } from '../types';
import { SYNTHETICS_API_URLS } from '../../../common/constants';
import type { DEFAULT_ALERT_RESPONSE } from '../../../common/types/default_alerts';
Expand All @@ -15,8 +15,8 @@ export const enableDefaultAlertingRoute: SyntheticsRestApiRouteFactory = () => (
path: SYNTHETICS_API_URLS.ENABLE_DEFAULT_ALERTING,
validate: {},
handler: async ({ context, server, savedObjectsClient }): Promise<DEFAULT_ALERT_RESPONSE> => {
const defaultAlertService = new DefaultAlertService(context, server, savedObjectsClient);
const defaultAlertService = new DefaultRuleService(context, server, savedObjectsClient);

return defaultAlertService.setupDefaultAlerts();
return defaultAlertService.setupDefaultRules();
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
SYNTHETICS_STATUS_RULE,
SYNTHETICS_TLS_RULE,
} from '../../../common/constants/synthetics_alerts';
import { DefaultAlertService } from './default_alert_service';
import { DefaultRuleService } from './default_alert_service';
import type { SyntheticsRestApiRouteFactory } from '../types';
import { SYNTHETICS_API_URLS } from '../../../common/constants';
import type { DEFAULT_ALERT_RESPONSE } from '../../../common/types/default_alerts';
Expand All @@ -19,7 +19,7 @@ export const getDefaultAlertingRoute: SyntheticsRestApiRouteFactory = () => ({
path: SYNTHETICS_API_URLS.ENABLE_DEFAULT_ALERTING,
validate: {},
handler: async ({ context, server, savedObjectsClient }): Promise<DEFAULT_ALERT_RESPONSE> => {
const defaultAlertService = new DefaultAlertService(context, server, savedObjectsClient);
const defaultAlertService = new DefaultRuleService(context, server, savedObjectsClient);
const statusRule = defaultAlertService.getExistingAlert(SYNTHETICS_STATUS_RULE);
const tlsRule = defaultAlertService.getExistingAlert(SYNTHETICS_TLS_RULE);
const [status, tls] = await Promise.all([statusRule, tlsRule]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import { getSyntheticsDynamicSettings } from '../../saved_objects/synthetics_settings';
import { DefaultAlertService } from './default_alert_service';
import { DefaultRuleService } from './default_alert_service';
import type { SyntheticsRestApiRouteFactory } from '../types';
import { SYNTHETICS_API_URLS } from '../../../common/constants';
import type { DEFAULT_ALERT_RESPONSE } from '../../../common/types/default_alerts';
Expand All @@ -16,7 +16,7 @@ export const updateDefaultAlertingRoute: SyntheticsRestApiRouteFactory = () => (
path: SYNTHETICS_API_URLS.ENABLE_DEFAULT_ALERTING,
validate: {},
handler: async ({ context, server, savedObjectsClient }): Promise<DEFAULT_ALERT_RESPONSE> => {
const defaultAlertService = new DefaultAlertService(context, server, savedObjectsClient);
const defaultAlertService = new DefaultRuleService(context, server, savedObjectsClient);
const { defaultTLSRuleEnabled, defaultStatusRuleEnabled } = await getSyntheticsDynamicSettings(
savedObjectsClient
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
DEFAULT_NAMESPACE_STRING,
} from '../../../../common/constants/monitor_defaults';
import { triggerTestNow } from '../../synthetics_service/test_now_monitor';
import { DefaultAlertService } from '../../default_alerts/default_alert_service';
import { DefaultRuleService } from '../../default_alerts/default_alert_service';
import type { RouteContext } from '../../types';
import { formatTelemetryEvent, sendTelemetryEvents } from '../../telemetry/monitor_upgrade_sender';
import { formatKibanaNamespace } from '../../../../common/formatters';
Expand Down Expand Up @@ -235,9 +235,9 @@ export class AddEditMonitorAPI {

try {
// we do this async, so we don't block the user, error handling will be done on the UI via separate api
const defaultAlertService = new DefaultAlertService(context, server, savedObjectsClient);
const defaultAlertService = new DefaultRuleService(context, server, savedObjectsClient);
defaultAlertService
.setupDefaultAlerts()
.setupDefaultRules()
.then(() => {
server.logger.debug(`Successfully created default alert for monitor: ${name}`);
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ import { getFixtureJson } from './helpers/get_fixture_json';
import { addMonitorAPIHelper, omitMonitorKeys } from './create_monitor';
import { PrivateLocationTestService } from '../../services/synthetics_private_location';

const TEST_INDEX_CONNECTOR_NAME = 'synthetics-default-alerting-test';

export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
describe('EnableDefaultAlerting', function () {
const supertest = getService('supertestWithoutAuth');
const kibanaServer = getService('kibanaServer');
const retry = getService('retry');
const samlAuth = getService('samlAuth');
const alerting = getService('alertingApi');

let _httpMonitorJson: HTTPFields;
let httpMonitorJson: HTTPFields;
Expand All @@ -37,12 +40,18 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {

after(async () => {
await kibanaServer.savedObjects.cleanStandardList();
await alerting.deleteAllActionConnectors({ roleAuthc: editorUser });
});

before(async () => {
await kibanaServer.savedObjects.cleanStandardList();
_httpMonitorJson = getFixtureJson('http_monitor');
editorUser = await samlAuth.createM2mApiKeyWithRoleScope('editor');
await alerting.createIndexConnector({
roleAuthc: editorUser,
name: TEST_INDEX_CONNECTOR_NAME,
indexName: 'synthetics-*',
});
});

beforeEach(async () => {
Expand All @@ -58,7 +67,10 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
.put(SYNTHETICS_API_URLS.DYNAMIC_SETTINGS)
.set(editorUser.apiKeyHeader)
.set(samlAuth.getInternalRequestHeader())
.send(DYNAMIC_SETTINGS_DEFAULTS)
.send({
...DYNAMIC_SETTINGS_DEFAULTS,
defaultConnectors: [TEST_INDEX_CONNECTOR_NAME],
})
.expect(200);
});

Expand Down