[Alerting] renames Resolved action group to Recovered (#84123)
This PR changes the default term from “Resolved” to “Recovered”, as it fits most use cases and we feel users are most likely to understand its meaning across domains.
This commit is contained in:
parent
4507865d10
commit
7dcaff5ddd
|
@ -6,13 +6,13 @@
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { ActionGroup } from './alert_type';
|
import { ActionGroup } from './alert_type';
|
||||||
|
|
||||||
export const ResolvedActionGroup: ActionGroup = {
|
export const RecoveredActionGroup: ActionGroup = {
|
||||||
id: 'resolved',
|
id: 'recovered',
|
||||||
name: i18n.translate('xpack.alerts.builtinActionGroups.resolved', {
|
name: i18n.translate('xpack.alerts.builtinActionGroups.recovered', {
|
||||||
defaultMessage: 'Resolved',
|
defaultMessage: 'Recovered',
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getBuiltinActionGroups(): ActionGroup[] {
|
export function getBuiltinActionGroups(): ActionGroup[] {
|
||||||
return [ResolvedActionGroup];
|
return [RecoveredActionGroup];
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,8 +105,8 @@ describe('register()', () => {
|
||||||
name: 'Default',
|
name: 'Default',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'resolved',
|
id: 'recovered',
|
||||||
name: 'Resolved',
|
name: 'Recovered',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
defaultActionGroupId: 'default',
|
defaultActionGroupId: 'default',
|
||||||
|
@ -117,7 +117,7 @@ describe('register()', () => {
|
||||||
|
|
||||||
expect(() => registry.register(alertType)).toThrowError(
|
expect(() => registry.register(alertType)).toThrowError(
|
||||||
new Error(
|
new Error(
|
||||||
`Alert type [id="${alertType.id}"] cannot be registered. Action groups [resolved] are reserved by the framework.`
|
`Alert type [id="${alertType.id}"] cannot be registered. Action groups [recovered] are reserved by the framework.`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -229,8 +229,8 @@ describe('get()', () => {
|
||||||
"name": "Default",
|
"name": "Default",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"id": "resolved",
|
"id": "recovered",
|
||||||
"name": "Resolved",
|
"name": "Recovered",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"actionVariables": Object {
|
"actionVariables": Object {
|
||||||
|
@ -287,8 +287,8 @@ describe('list()', () => {
|
||||||
"name": "Test Action Group",
|
"name": "Test Action Group",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"id": "resolved",
|
"id": "recovered",
|
||||||
"name": "Resolved",
|
"name": "Recovered",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"actionVariables": Object {
|
"actionVariables": Object {
|
||||||
|
|
|
@ -122,7 +122,7 @@ describe('getAlertInstanceSummary()', () => {
|
||||||
.addActiveInstance('instance-previously-active', 'action group B')
|
.addActiveInstance('instance-previously-active', 'action group B')
|
||||||
.advanceTime(10000)
|
.advanceTime(10000)
|
||||||
.addExecute()
|
.addExecute()
|
||||||
.addResolvedInstance('instance-previously-active')
|
.addRecoveredInstance('instance-previously-active')
|
||||||
.addActiveInstance('instance-currently-active', 'action group A')
|
.addActiveInstance('instance-currently-active', 'action group A')
|
||||||
.getEvents();
|
.getEvents();
|
||||||
const eventsResult = {
|
const eventsResult = {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import { SanitizedAlert, AlertInstanceSummary } from '../types';
|
import { SanitizedAlert, AlertInstanceSummary } from '../types';
|
||||||
import { IValidatedEvent } from '../../../event_log/server';
|
import { IValidatedEvent } from '../../../event_log/server';
|
||||||
import { EVENT_LOG_ACTIONS, EVENT_LOG_PROVIDER } from '../plugin';
|
import { EVENT_LOG_ACTIONS, EVENT_LOG_PROVIDER, LEGACY_EVENT_LOG_ACTIONS } from '../plugin';
|
||||||
import { alertInstanceSummaryFromEventLog } from './alert_instance_summary_from_event_log';
|
import { alertInstanceSummaryFromEventLog } from './alert_instance_summary_from_event_log';
|
||||||
|
|
||||||
const ONE_HOUR_IN_MILLIS = 60 * 60 * 1000;
|
const ONE_HOUR_IN_MILLIS = 60 * 60 * 1000;
|
||||||
|
@ -189,7 +189,43 @@ describe('alertInstanceSummaryFromEventLog', () => {
|
||||||
.addActiveInstance('instance-1', 'action group A')
|
.addActiveInstance('instance-1', 'action group A')
|
||||||
.advanceTime(10000)
|
.advanceTime(10000)
|
||||||
.addExecute()
|
.addExecute()
|
||||||
.addResolvedInstance('instance-1')
|
.addRecoveredInstance('instance-1')
|
||||||
|
.getEvents();
|
||||||
|
|
||||||
|
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
|
||||||
|
alert,
|
||||||
|
events,
|
||||||
|
dateStart,
|
||||||
|
dateEnd,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { lastRun, status, instances } = summary;
|
||||||
|
expect({ lastRun, status, instances }).toMatchInlineSnapshot(`
|
||||||
|
Object {
|
||||||
|
"instances": Object {
|
||||||
|
"instance-1": Object {
|
||||||
|
"actionGroupId": undefined,
|
||||||
|
"activeStartDate": undefined,
|
||||||
|
"muted": false,
|
||||||
|
"status": "OK",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"lastRun": "2020-06-18T00:00:10.000Z",
|
||||||
|
"status": "OK",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('legacy alert with currently inactive instance', async () => {
|
||||||
|
const alert = createAlert({});
|
||||||
|
const eventsFactory = new EventsFactory();
|
||||||
|
const events = eventsFactory
|
||||||
|
.addExecute()
|
||||||
|
.addNewInstance('instance-1')
|
||||||
|
.addActiveInstance('instance-1', 'action group A')
|
||||||
|
.advanceTime(10000)
|
||||||
|
.addExecute()
|
||||||
|
.addLegacyResolvedInstance('instance-1')
|
||||||
.getEvents();
|
.getEvents();
|
||||||
|
|
||||||
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
|
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
|
||||||
|
@ -224,7 +260,7 @@ describe('alertInstanceSummaryFromEventLog', () => {
|
||||||
.addActiveInstance('instance-1', 'action group A')
|
.addActiveInstance('instance-1', 'action group A')
|
||||||
.advanceTime(10000)
|
.advanceTime(10000)
|
||||||
.addExecute()
|
.addExecute()
|
||||||
.addResolvedInstance('instance-1')
|
.addRecoveredInstance('instance-1')
|
||||||
.getEvents();
|
.getEvents();
|
||||||
|
|
||||||
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
|
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
|
||||||
|
@ -406,7 +442,7 @@ describe('alertInstanceSummaryFromEventLog', () => {
|
||||||
.advanceTime(10000)
|
.advanceTime(10000)
|
||||||
.addExecute()
|
.addExecute()
|
||||||
.addActiveInstance('instance-1', 'action group A')
|
.addActiveInstance('instance-1', 'action group A')
|
||||||
.addResolvedInstance('instance-2')
|
.addRecoveredInstance('instance-2')
|
||||||
.getEvents();
|
.getEvents();
|
||||||
|
|
||||||
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
|
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
|
||||||
|
@ -451,7 +487,7 @@ describe('alertInstanceSummaryFromEventLog', () => {
|
||||||
.advanceTime(10000)
|
.advanceTime(10000)
|
||||||
.addExecute()
|
.addExecute()
|
||||||
.addActiveInstance('instance-1', 'action group A')
|
.addActiveInstance('instance-1', 'action group A')
|
||||||
.addResolvedInstance('instance-2')
|
.addRecoveredInstance('instance-2')
|
||||||
.advanceTime(10000)
|
.advanceTime(10000)
|
||||||
.addExecute()
|
.addExecute()
|
||||||
.addActiveInstance('instance-1', 'action group B')
|
.addActiveInstance('instance-1', 'action group B')
|
||||||
|
@ -561,12 +597,24 @@ export class EventsFactory {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addResolvedInstance(instanceId: string): EventsFactory {
|
addRecoveredInstance(instanceId: string): EventsFactory {
|
||||||
this.events.push({
|
this.events.push({
|
||||||
'@timestamp': this.date,
|
'@timestamp': this.date,
|
||||||
event: {
|
event: {
|
||||||
provider: EVENT_LOG_PROVIDER,
|
provider: EVENT_LOG_PROVIDER,
|
||||||
action: EVENT_LOG_ACTIONS.resolvedInstance,
|
action: EVENT_LOG_ACTIONS.recoveredInstance,
|
||||||
|
},
|
||||||
|
kibana: { alerting: { instance_id: instanceId } },
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
addLegacyResolvedInstance(instanceId: string): EventsFactory {
|
||||||
|
this.events.push({
|
||||||
|
'@timestamp': this.date,
|
||||||
|
event: {
|
||||||
|
provider: EVENT_LOG_PROVIDER,
|
||||||
|
action: LEGACY_EVENT_LOG_ACTIONS.resolvedInstance,
|
||||||
},
|
},
|
||||||
kibana: { alerting: { instance_id: instanceId } },
|
kibana: { alerting: { instance_id: instanceId } },
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import { SanitizedAlert, AlertInstanceSummary, AlertInstanceStatus } from '../types';
|
import { SanitizedAlert, AlertInstanceSummary, AlertInstanceStatus } from '../types';
|
||||||
import { IEvent } from '../../../event_log/server';
|
import { IEvent } from '../../../event_log/server';
|
||||||
import { EVENT_LOG_ACTIONS, EVENT_LOG_PROVIDER } from '../plugin';
|
import { EVENT_LOG_ACTIONS, EVENT_LOG_PROVIDER, LEGACY_EVENT_LOG_ACTIONS } from '../plugin';
|
||||||
|
|
||||||
export interface AlertInstanceSummaryFromEventLogParams {
|
export interface AlertInstanceSummaryFromEventLogParams {
|
||||||
alert: SanitizedAlert;
|
alert: SanitizedAlert;
|
||||||
|
@ -80,7 +80,8 @@ export function alertInstanceSummaryFromEventLog(
|
||||||
status.status = 'Active';
|
status.status = 'Active';
|
||||||
status.actionGroupId = event?.kibana?.alerting?.action_group_id;
|
status.actionGroupId = event?.kibana?.alerting?.action_group_id;
|
||||||
break;
|
break;
|
||||||
case EVENT_LOG_ACTIONS.resolvedInstance:
|
case LEGACY_EVENT_LOG_ACTIONS.resolvedInstance:
|
||||||
|
case EVENT_LOG_ACTIONS.recoveredInstance:
|
||||||
status.status = 'OK';
|
status.status = 'OK';
|
||||||
status.activeStartDate = undefined;
|
status.activeStartDate = undefined;
|
||||||
status.actionGroupId = undefined;
|
status.actionGroupId = undefined;
|
||||||
|
|
|
@ -82,9 +82,12 @@ export const EVENT_LOG_ACTIONS = {
|
||||||
execute: 'execute',
|
execute: 'execute',
|
||||||
executeAction: 'execute-action',
|
executeAction: 'execute-action',
|
||||||
newInstance: 'new-instance',
|
newInstance: 'new-instance',
|
||||||
resolvedInstance: 'resolved-instance',
|
recoveredInstance: 'recovered-instance',
|
||||||
activeInstance: 'active-instance',
|
activeInstance: 'active-instance',
|
||||||
};
|
};
|
||||||
|
export const LEGACY_EVENT_LOG_ACTIONS = {
|
||||||
|
resolvedInstance: 'resolved-instance',
|
||||||
|
};
|
||||||
|
|
||||||
export interface PluginSetupContract {
|
export interface PluginSetupContract {
|
||||||
registerType: AlertTypeRegistry['register'];
|
registerType: AlertTypeRegistry['register'];
|
||||||
|
|
|
@ -26,12 +26,12 @@ import { alertsMock, alertsClientMock } from '../mocks';
|
||||||
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
|
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
|
||||||
import { IEventLogger } from '../../../event_log/server';
|
import { IEventLogger } from '../../../event_log/server';
|
||||||
import { SavedObjectsErrorHelpers } from '../../../../../src/core/server';
|
import { SavedObjectsErrorHelpers } from '../../../../../src/core/server';
|
||||||
import { Alert, ResolvedActionGroup } from '../../common';
|
import { Alert, RecoveredActionGroup } from '../../common';
|
||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
const alertType = {
|
const alertType = {
|
||||||
id: 'test',
|
id: 'test',
|
||||||
name: 'My test alert',
|
name: 'My test alert',
|
||||||
actionGroups: [{ id: 'default', name: 'Default' }, ResolvedActionGroup],
|
actionGroups: [{ id: 'default', name: 'Default' }, RecoveredActionGroup],
|
||||||
defaultActionGroupId: 'default',
|
defaultActionGroupId: 'default',
|
||||||
executor: jest.fn(),
|
executor: jest.fn(),
|
||||||
producer: 'alerts',
|
producer: 'alerts',
|
||||||
|
@ -114,7 +114,7 @@ describe('Task Runner', () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: ResolvedActionGroup.id,
|
group: RecoveredActionGroup.id,
|
||||||
id: '2',
|
id: '2',
|
||||||
actionTypeId: 'action',
|
actionTypeId: 'action',
|
||||||
params: {
|
params: {
|
||||||
|
@ -517,7 +517,7 @@ describe('Task Runner', () => {
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('fire resolved actions for execution for the alertInstances which is in the resolved state', async () => {
|
test('fire recovered actions for execution for the alertInstances which is in the recovered state', async () => {
|
||||||
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
|
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
|
||||||
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
|
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ describe('Task Runner', () => {
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
"event": Object {
|
"event": Object {
|
||||||
"action": "resolved-instance",
|
"action": "recovered-instance",
|
||||||
},
|
},
|
||||||
"kibana": Object {
|
"kibana": Object {
|
||||||
"alerting": Object {
|
"alerting": Object {
|
||||||
|
@ -666,7 +666,7 @@ describe('Task Runner', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"message": "test:1: 'alert-name' resolved instance: '2'",
|
"message": "test:1: 'alert-name' instance '2' has recovered",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
Array [
|
Array [
|
||||||
|
|
|
@ -39,7 +39,7 @@ import { IEvent, IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '../../../event_l
|
||||||
import { isAlertSavedObjectNotFoundError } from '../lib/is_alert_not_found_error';
|
import { isAlertSavedObjectNotFoundError } from '../lib/is_alert_not_found_error';
|
||||||
import { AlertsClient } from '../alerts_client';
|
import { AlertsClient } from '../alerts_client';
|
||||||
import { partiallyUpdateAlert } from '../saved_objects';
|
import { partiallyUpdateAlert } from '../saved_objects';
|
||||||
import { ResolvedActionGroup } from '../../common';
|
import { RecoveredActionGroup } from '../../common';
|
||||||
|
|
||||||
const FALLBACK_RETRY_INTERVAL = '5m';
|
const FALLBACK_RETRY_INTERVAL = '5m';
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ export class TaskRunner {
|
||||||
alertInstance.hasScheduledActions()
|
alertInstance.hasScheduledActions()
|
||||||
);
|
);
|
||||||
|
|
||||||
generateNewAndResolvedInstanceEvents({
|
generateNewAndRecoveredInstanceEvents({
|
||||||
eventLogger,
|
eventLogger,
|
||||||
originalAlertInstances,
|
originalAlertInstances,
|
||||||
currentAlertInstances: instancesWithScheduledActions,
|
currentAlertInstances: instancesWithScheduledActions,
|
||||||
|
@ -229,7 +229,7 @@ export class TaskRunner {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!muteAll) {
|
if (!muteAll) {
|
||||||
scheduleActionsForResolvedInstances(
|
scheduleActionsForRecoveredInstances(
|
||||||
alertInstances,
|
alertInstances,
|
||||||
executionHandler,
|
executionHandler,
|
||||||
originalAlertInstances,
|
originalAlertInstances,
|
||||||
|
@ -436,7 +436,7 @@ export class TaskRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GenerateNewAndResolvedInstanceEventsParams {
|
interface GenerateNewAndRecoveredInstanceEventsParams {
|
||||||
eventLogger: IEventLogger;
|
eventLogger: IEventLogger;
|
||||||
originalAlertInstances: Dictionary<AlertInstance>;
|
originalAlertInstances: Dictionary<AlertInstance>;
|
||||||
currentAlertInstances: Dictionary<AlertInstance>;
|
currentAlertInstances: Dictionary<AlertInstance>;
|
||||||
|
@ -445,18 +445,20 @@ interface GenerateNewAndResolvedInstanceEventsParams {
|
||||||
namespace: string | undefined;
|
namespace: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateNewAndResolvedInstanceEvents(params: GenerateNewAndResolvedInstanceEventsParams) {
|
function generateNewAndRecoveredInstanceEvents(
|
||||||
|
params: GenerateNewAndRecoveredInstanceEventsParams
|
||||||
|
) {
|
||||||
const { eventLogger, alertId, namespace, currentAlertInstances, originalAlertInstances } = params;
|
const { eventLogger, alertId, namespace, currentAlertInstances, originalAlertInstances } = params;
|
||||||
const originalAlertInstanceIds = Object.keys(originalAlertInstances);
|
const originalAlertInstanceIds = Object.keys(originalAlertInstances);
|
||||||
const currentAlertInstanceIds = Object.keys(currentAlertInstances);
|
const currentAlertInstanceIds = Object.keys(currentAlertInstances);
|
||||||
|
|
||||||
const newIds = without(currentAlertInstanceIds, ...originalAlertInstanceIds);
|
const newIds = without(currentAlertInstanceIds, ...originalAlertInstanceIds);
|
||||||
const resolvedIds = without(originalAlertInstanceIds, ...currentAlertInstanceIds);
|
const recoveredIds = without(originalAlertInstanceIds, ...currentAlertInstanceIds);
|
||||||
|
|
||||||
for (const id of resolvedIds) {
|
for (const id of recoveredIds) {
|
||||||
const actionGroup = originalAlertInstances[id].getLastScheduledActions()?.group;
|
const actionGroup = originalAlertInstances[id].getLastScheduledActions()?.group;
|
||||||
const message = `${params.alertLabel} resolved instance: '${id}'`;
|
const message = `${params.alertLabel} instance '${id}' has recovered`;
|
||||||
logInstanceEvent(id, EVENT_LOG_ACTIONS.resolvedInstance, message, actionGroup);
|
logInstanceEvent(id, EVENT_LOG_ACTIONS.recoveredInstance, message, actionGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const id of newIds) {
|
for (const id of newIds) {
|
||||||
|
@ -496,7 +498,7 @@ function generateNewAndResolvedInstanceEvents(params: GenerateNewAndResolvedInst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function scheduleActionsForResolvedInstances(
|
function scheduleActionsForRecoveredInstances(
|
||||||
alertInstancesMap: Record<string, AlertInstance>,
|
alertInstancesMap: Record<string, AlertInstance>,
|
||||||
executionHandler: ReturnType<typeof createExecutionHandler>,
|
executionHandler: ReturnType<typeof createExecutionHandler>,
|
||||||
originalAlertInstances: Record<string, AlertInstance>,
|
originalAlertInstances: Record<string, AlertInstance>,
|
||||||
|
@ -505,22 +507,22 @@ function scheduleActionsForResolvedInstances(
|
||||||
) {
|
) {
|
||||||
const currentAlertInstanceIds = Object.keys(currentAlertInstances);
|
const currentAlertInstanceIds = Object.keys(currentAlertInstances);
|
||||||
const originalAlertInstanceIds = Object.keys(originalAlertInstances);
|
const originalAlertInstanceIds = Object.keys(originalAlertInstances);
|
||||||
const resolvedIds = without(
|
const recoveredIds = without(
|
||||||
originalAlertInstanceIds,
|
originalAlertInstanceIds,
|
||||||
...currentAlertInstanceIds,
|
...currentAlertInstanceIds,
|
||||||
...mutedInstanceIds
|
...mutedInstanceIds
|
||||||
);
|
);
|
||||||
for (const id of resolvedIds) {
|
for (const id of recoveredIds) {
|
||||||
const instance = alertInstancesMap[id];
|
const instance = alertInstancesMap[id];
|
||||||
instance.updateLastScheduledActions(ResolvedActionGroup.id);
|
instance.updateLastScheduledActions(RecoveredActionGroup.id);
|
||||||
instance.unscheduleActions();
|
instance.unscheduleActions();
|
||||||
executionHandler({
|
executionHandler({
|
||||||
actionGroup: ResolvedActionGroup.id,
|
actionGroup: RecoveredActionGroup.id,
|
||||||
context: {},
|
context: {},
|
||||||
state: {},
|
state: {},
|
||||||
alertInstanceId: id,
|
alertInstanceId: id,
|
||||||
});
|
});
|
||||||
instance.scheduleActions(ResolvedActionGroup.id);
|
instance.scheduleActions(RecoveredActionGroup.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import moment from 'moment';
|
||||||
import { getCustomMetricLabel } from '../../../../common/formatters/get_custom_metric_label';
|
import { getCustomMetricLabel } from '../../../../common/formatters/get_custom_metric_label';
|
||||||
import { toMetricOpt } from '../../../../common/snapshot_metric_i18n';
|
import { toMetricOpt } from '../../../../common/snapshot_metric_i18n';
|
||||||
import { AlertStates, InventoryMetricConditions } from './types';
|
import { AlertStates, InventoryMetricConditions } from './types';
|
||||||
import { ResolvedActionGroup } from '../../../../../alerts/common';
|
import { RecoveredActionGroup } from '../../../../../alerts/common';
|
||||||
import { AlertExecutorOptions } from '../../../../../alerts/server';
|
import { AlertExecutorOptions } from '../../../../../alerts/server';
|
||||||
import { InventoryItemType, SnapshotMetricType } from '../../../../common/inventory_models/types';
|
import { InventoryItemType, SnapshotMetricType } from '../../../../common/inventory_models/types';
|
||||||
import { InfraBackendLibs } from '../../infra_types';
|
import { InfraBackendLibs } from '../../infra_types';
|
||||||
|
@ -103,7 +103,7 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
|
||||||
}
|
}
|
||||||
if (reason) {
|
if (reason) {
|
||||||
const actionGroupId =
|
const actionGroupId =
|
||||||
nextState === AlertStates.OK ? ResolvedActionGroup.id : FIRED_ACTIONS.id;
|
nextState === AlertStates.OK ? RecoveredActionGroup.id : FIRED_ACTIONS.id;
|
||||||
alertInstance.scheduleActions(actionGroupId, {
|
alertInstance.scheduleActions(actionGroupId, {
|
||||||
group: item,
|
group: item,
|
||||||
alertState: stateToAlertMessage[nextState],
|
alertState: stateToAlertMessage[nextState],
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { createMetricThresholdExecutor, FIRED_ACTIONS } from './metric_threshold_executor';
|
import { createMetricThresholdExecutor, FIRED_ACTIONS } from './metric_threshold_executor';
|
||||||
import { Comparator, AlertStates } from './types';
|
import { Comparator, AlertStates } from './types';
|
||||||
import * as mocks from './test_mocks';
|
import * as mocks from './test_mocks';
|
||||||
import { ResolvedActionGroup } from '../../../../../alerts/common';
|
import { RecoveredActionGroup } from '../../../../../alerts/common';
|
||||||
import { AlertExecutorOptions } from '../../../../../alerts/server';
|
import { AlertExecutorOptions } from '../../../../../alerts/server';
|
||||||
import {
|
import {
|
||||||
alertsMock,
|
alertsMock,
|
||||||
|
@ -367,7 +367,7 @@ describe('The metric threshold alert type', () => {
|
||||||
expect(mostRecentAction(instanceID).id).toBe(FIRED_ACTIONS.id);
|
expect(mostRecentAction(instanceID).id).toBe(FIRED_ACTIONS.id);
|
||||||
expect(getState(instanceID).alertState).toBe(AlertStates.ALERT);
|
expect(getState(instanceID).alertState).toBe(AlertStates.ALERT);
|
||||||
await execute([2]);
|
await execute([2]);
|
||||||
expect(mostRecentAction(instanceID).id).toBe(ResolvedActionGroup.id);
|
expect(mostRecentAction(instanceID).id).toBe(RecoveredActionGroup.id);
|
||||||
expect(getState(instanceID).alertState).toBe(AlertStates.OK);
|
expect(getState(instanceID).alertState).toBe(AlertStates.OK);
|
||||||
});
|
});
|
||||||
test('does not continue to send a recovery alert if the metric is still OK', async () => {
|
test('does not continue to send a recovery alert if the metric is still OK', async () => {
|
||||||
|
@ -383,7 +383,7 @@ describe('The metric threshold alert type', () => {
|
||||||
expect(mostRecentAction(instanceID).id).toBe(FIRED_ACTIONS.id);
|
expect(mostRecentAction(instanceID).id).toBe(FIRED_ACTIONS.id);
|
||||||
expect(getState(instanceID).alertState).toBe(AlertStates.ALERT);
|
expect(getState(instanceID).alertState).toBe(AlertStates.ALERT);
|
||||||
await execute([2]);
|
await execute([2]);
|
||||||
expect(mostRecentAction(instanceID).id).toBe(ResolvedActionGroup.id);
|
expect(mostRecentAction(instanceID).id).toBe(RecoveredActionGroup.id);
|
||||||
expect(getState(instanceID).alertState).toBe(AlertStates.OK);
|
expect(getState(instanceID).alertState).toBe(AlertStates.OK);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { first, last } from 'lodash';
|
import { first, last } from 'lodash';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { ResolvedActionGroup } from '../../../../../alerts/common';
|
import { RecoveredActionGroup } from '../../../../../alerts/common';
|
||||||
import { AlertExecutorOptions } from '../../../../../alerts/server';
|
import { AlertExecutorOptions } from '../../../../../alerts/server';
|
||||||
import { InfraBackendLibs } from '../../infra_types';
|
import { InfraBackendLibs } from '../../infra_types';
|
||||||
import {
|
import {
|
||||||
|
@ -89,7 +89,7 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) =>
|
||||||
const firstResult = first(alertResults);
|
const firstResult = first(alertResults);
|
||||||
const timestamp = (firstResult && firstResult[group].timestamp) ?? moment().toISOString();
|
const timestamp = (firstResult && firstResult[group].timestamp) ?? moment().toISOString();
|
||||||
const actionGroupId =
|
const actionGroupId =
|
||||||
nextState === AlertStates.OK ? ResolvedActionGroup.id : FIRED_ACTIONS.id;
|
nextState === AlertStates.OK ? RecoveredActionGroup.id : FIRED_ACTIONS.id;
|
||||||
alertInstance.scheduleActions(actionGroupId, {
|
alertInstance.scheduleActions(actionGroupId, {
|
||||||
group,
|
group,
|
||||||
alertState: stateToAlertMessage[nextState],
|
alertState: stateToAlertMessage[nextState],
|
||||||
|
|
|
@ -16,10 +16,10 @@ export const routeToConnectors = `/connectors`;
|
||||||
export const routeToAlerts = `/alerts`;
|
export const routeToAlerts = `/alerts`;
|
||||||
export const routeToAlertDetails = `/alert/:alertId`;
|
export const routeToAlertDetails = `/alert/:alertId`;
|
||||||
|
|
||||||
export const resolvedActionGroupMessage = i18n.translate(
|
export const recoveredActionGroupMessage = i18n.translate(
|
||||||
'xpack.triggersActionsUI.sections.actionForm.ResolvedMessage',
|
'xpack.triggersActionsUI.sections.actionForm.RecoveredMessage',
|
||||||
{
|
{
|
||||||
defaultMessage: 'Resolved',
|
defaultMessage: 'Recovered',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,9 @@ import { act } from 'react-dom/test-utils';
|
||||||
import { actionTypeRegistryMock } from '../../action_type_registry.mock';
|
import { actionTypeRegistryMock } from '../../action_type_registry.mock';
|
||||||
import { ValidationResult, Alert, AlertAction } from '../../../types';
|
import { ValidationResult, Alert, AlertAction } from '../../../types';
|
||||||
import ActionForm from './action_form';
|
import ActionForm from './action_form';
|
||||||
import { ResolvedActionGroup } from '../../../../../alerts/common';
|
import { RecoveredActionGroup } from '../../../../../alerts/common';
|
||||||
import { useKibana } from '../../../common/lib/kibana';
|
import { useKibana } from '../../../common/lib/kibana';
|
||||||
|
import { EuiScreenReaderOnly } from '@elastic/eui';
|
||||||
jest.mock('../../../common/lib/kibana');
|
jest.mock('../../../common/lib/kibana');
|
||||||
jest.mock('../../lib/action_connector_api', () => ({
|
jest.mock('../../lib/action_connector_api', () => ({
|
||||||
loadAllActions: jest.fn(),
|
loadAllActions: jest.fn(),
|
||||||
|
@ -228,7 +229,7 @@ describe('action_form', () => {
|
||||||
}}
|
}}
|
||||||
actionGroups={[
|
actionGroups={[
|
||||||
{ id: 'default', name: 'Default' },
|
{ id: 'default', name: 'Default' },
|
||||||
{ id: 'resolved', name: 'Resolved' },
|
{ id: 'recovered', name: 'Recovered' },
|
||||||
]}
|
]}
|
||||||
setActionGroupIdByIndex={(group: string, index: number) => {
|
setActionGroupIdByIndex={(group: string, index: number) => {
|
||||||
initialAlert.actions[index].group = group;
|
initialAlert.actions[index].group = group;
|
||||||
|
@ -347,18 +348,18 @@ describe('action_form', () => {
|
||||||
"value": "default",
|
"value": "default",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"data-test-subj": "addNewActionConnectorActionGroup-0-option-resolved",
|
"data-test-subj": "addNewActionConnectorActionGroup-0-option-recovered",
|
||||||
"inputDisplay": "Resolved",
|
"inputDisplay": "Recovered",
|
||||||
"value": "resolved",
|
"value": "recovered",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders selected Resolved action group', async () => {
|
it('renders selected Recovered action group', async () => {
|
||||||
const wrapper = await setup([
|
const wrapper = await setup([
|
||||||
{
|
{
|
||||||
group: ResolvedActionGroup.id,
|
group: RecoveredActionGroup.id,
|
||||||
id: 'test',
|
id: 'test',
|
||||||
actionTypeId: actionType.id,
|
actionTypeId: actionType.id,
|
||||||
params: {
|
params: {
|
||||||
|
@ -381,15 +382,17 @@ describe('action_form', () => {
|
||||||
"value": "default",
|
"value": "default",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"data-test-subj": "addNewActionConnectorActionGroup-0-option-resolved",
|
"data-test-subj": "addNewActionConnectorActionGroup-0-option-recovered",
|
||||||
"inputDisplay": "Resolved",
|
"inputDisplay": "Recovered",
|
||||||
"value": "resolved",
|
"value": "recovered",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
`);
|
`);
|
||||||
expect(actionGroupsSelect.first().text()).toEqual(
|
|
||||||
'Select an option: Resolved, is selectedResolved'
|
expect(actionGroupsSelect.first().find(EuiScreenReaderOnly).text()).toEqual(
|
||||||
|
'Select an option: Recovered, is selected'
|
||||||
);
|
);
|
||||||
|
expect(actionGroupsSelect.first().find('button').first().text()).toEqual('Recovered');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders available connectors for the selected action type', async () => {
|
it('renders available connectors for the selected action type', async () => {
|
||||||
|
|
|
@ -26,7 +26,7 @@ import {
|
||||||
EuiBadge,
|
EuiBadge,
|
||||||
EuiErrorBoundary,
|
EuiErrorBoundary,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { AlertActionParam, ResolvedActionGroup } from '../../../../../alerts/common';
|
import { AlertActionParam, RecoveredActionGroup } from '../../../../../alerts/common';
|
||||||
import {
|
import {
|
||||||
IErrorObject,
|
IErrorObject,
|
||||||
AlertAction,
|
AlertAction,
|
||||||
|
@ -40,7 +40,7 @@ import { checkActionFormActionTypeEnabled } from '../../lib/check_action_type_en
|
||||||
import { hasSaveActionsCapability } from '../../lib/capabilities';
|
import { hasSaveActionsCapability } from '../../lib/capabilities';
|
||||||
import { ActionAccordionFormProps } from './action_form';
|
import { ActionAccordionFormProps } from './action_form';
|
||||||
import { transformActionVariables } from '../../lib/action_variables';
|
import { transformActionVariables } from '../../lib/action_variables';
|
||||||
import { resolvedActionGroupMessage } from '../../constants';
|
import { recoveredActionGroupMessage } from '../../constants';
|
||||||
import { useKibana } from '../../../common/lib/kibana';
|
import { useKibana } from '../../../common/lib/kibana';
|
||||||
import { getDefaultsForActionParams } from '../../lib/get_defaults_for_action_params';
|
import { getDefaultsForActionParams } from '../../lib/get_defaults_for_action_params';
|
||||||
|
|
||||||
|
@ -105,8 +105,8 @@ export const ActionTypeForm = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAvailableActionVariables(getAvailableActionVariables(messageVariables, actionItem.group));
|
setAvailableActionVariables(getAvailableActionVariables(messageVariables, actionItem.group));
|
||||||
const res =
|
const res =
|
||||||
actionItem.group === ResolvedActionGroup.id
|
actionItem.group === RecoveredActionGroup.id
|
||||||
? resolvedActionGroupMessage
|
? recoveredActionGroupMessage
|
||||||
: defaultActionMessage;
|
: defaultActionMessage;
|
||||||
setAvailableDefaultActionMessage(res);
|
setAvailableDefaultActionMessage(res);
|
||||||
const paramsDefaults = getDefaultsForActionParams(actionItem.actionTypeId, actionItem.group);
|
const paramsDefaults = getDefaultsForActionParams(actionItem.actionTypeId, actionItem.group);
|
||||||
|
@ -374,7 +374,7 @@ function getAvailableActionVariables(
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const filteredActionVariables =
|
const filteredActionVariables =
|
||||||
actionGroup === ResolvedActionGroup.id
|
actionGroup === RecoveredActionGroup.id
|
||||||
? { params: actionVariables.params, state: actionVariables.state }
|
? { params: actionVariables.params, state: actionVariables.state }
|
||||||
: actionVariables;
|
: actionVariables;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
|
||||||
const expectedNoOpType = {
|
const expectedNoOpType = {
|
||||||
actionGroups: [
|
actionGroups: [
|
||||||
{ id: 'default', name: 'Default' },
|
{ id: 'default', name: 'Default' },
|
||||||
{ id: 'resolved', name: 'Resolved' },
|
{ id: 'recovered', name: 'Recovered' },
|
||||||
],
|
],
|
||||||
defaultActionGroupId: 'default',
|
defaultActionGroupId: 'default',
|
||||||
id: 'test.noop',
|
id: 'test.noop',
|
||||||
|
@ -33,7 +33,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
|
||||||
const expectedRestrictedNoOpType = {
|
const expectedRestrictedNoOpType = {
|
||||||
actionGroups: [
|
actionGroups: [
|
||||||
{ id: 'default', name: 'Default' },
|
{ id: 'default', name: 'Default' },
|
||||||
{ id: 'resolved', name: 'Resolved' },
|
{ id: 'recovered', name: 'Recovered' },
|
||||||
],
|
],
|
||||||
defaultActionGroupId: 'default',
|
defaultActionGroupId: 'default',
|
||||||
id: 'test.restricted-noop',
|
id: 'test.restricted-noop',
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import expect from '@kbn/expect';
|
import expect from '@kbn/expect';
|
||||||
import { Response as SupertestResponse } from 'supertest';
|
import { Response as SupertestResponse } from 'supertest';
|
||||||
import { ResolvedActionGroup } from '../../../../../plugins/alerts/common';
|
import { RecoveredActionGroup } from '../../../../../plugins/alerts/common';
|
||||||
import { Space } from '../../../common/types';
|
import { Space } from '../../../common/types';
|
||||||
import { FtrProviderContext } from '../../../common/ftr_provider_context';
|
import { FtrProviderContext } from '../../../common/ftr_provider_context';
|
||||||
import {
|
import {
|
||||||
|
@ -137,7 +137,7 @@ instanceStateValue: true
|
||||||
await taskManagerUtils.waitForActionTaskParamsToBeCleanedUp(testStart);
|
await taskManagerUtils.waitForActionTaskParamsToBeCleanedUp(testStart);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fire actions when an alert instance is resolved', async () => {
|
it('should fire actions when an alert instance is recovered', async () => {
|
||||||
const reference = alertUtils.generateReference();
|
const reference = alertUtils.generateReference();
|
||||||
|
|
||||||
const { body: createdAction } = await supertestWithoutAuth
|
const { body: createdAction } = await supertestWithoutAuth
|
||||||
|
@ -174,12 +174,12 @@ instanceStateValue: true
|
||||||
params: {},
|
params: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: ResolvedActionGroup.id,
|
group: RecoveredActionGroup.id,
|
||||||
id: indexRecordActionId,
|
id: indexRecordActionId,
|
||||||
params: {
|
params: {
|
||||||
index: ES_TEST_INDEX_NAME,
|
index: ES_TEST_INDEX_NAME,
|
||||||
reference,
|
reference,
|
||||||
message: 'Resolved message',
|
message: 'Recovered message',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -194,10 +194,10 @@ instanceStateValue: true
|
||||||
await esTestIndexTool.waitForDocs('action:test.index-record', reference)
|
await esTestIndexTool.waitForDocs('action:test.index-record', reference)
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
expect(actionTestRecord._source.params.message).to.eql('Resolved message');
|
expect(actionTestRecord._source.params.message).to.eql('Recovered message');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not fire actions when an alert instance is resolved, but alert is muted', async () => {
|
it('should not fire actions when an alert instance is recovered, but alert is muted', async () => {
|
||||||
const testStart = new Date();
|
const testStart = new Date();
|
||||||
const reference = alertUtils.generateReference();
|
const reference = alertUtils.generateReference();
|
||||||
|
|
||||||
|
@ -237,12 +237,12 @@ instanceStateValue: true
|
||||||
params: {},
|
params: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: ResolvedActionGroup.id,
|
group: RecoveredActionGroup.id,
|
||||||
id: indexRecordActionId,
|
id: indexRecordActionId,
|
||||||
params: {
|
params: {
|
||||||
index: ES_TEST_INDEX_NAME,
|
index: ES_TEST_INDEX_NAME,
|
||||||
reference,
|
reference,
|
||||||
message: 'Resolved message',
|
message: 'Recovered message',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -78,7 +78,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
|
||||||
'execute-action',
|
'execute-action',
|
||||||
'new-instance',
|
'new-instance',
|
||||||
'active-instance',
|
'active-instance',
|
||||||
'resolved-instance',
|
'recovered-instance',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -87,25 +87,25 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
|
||||||
const executeEvents = getEventsByAction(events, 'execute');
|
const executeEvents = getEventsByAction(events, 'execute');
|
||||||
const executeActionEvents = getEventsByAction(events, 'execute-action');
|
const executeActionEvents = getEventsByAction(events, 'execute-action');
|
||||||
const newInstanceEvents = getEventsByAction(events, 'new-instance');
|
const newInstanceEvents = getEventsByAction(events, 'new-instance');
|
||||||
const resolvedInstanceEvents = getEventsByAction(events, 'resolved-instance');
|
const recoveredInstanceEvents = getEventsByAction(events, 'recovered-instance');
|
||||||
|
|
||||||
expect(executeEvents.length >= 4).to.be(true);
|
expect(executeEvents.length >= 4).to.be(true);
|
||||||
expect(executeActionEvents.length).to.be(2);
|
expect(executeActionEvents.length).to.be(2);
|
||||||
expect(newInstanceEvents.length).to.be(1);
|
expect(newInstanceEvents.length).to.be(1);
|
||||||
expect(resolvedInstanceEvents.length).to.be(1);
|
expect(recoveredInstanceEvents.length).to.be(1);
|
||||||
|
|
||||||
// make sure the events are in the right temporal order
|
// make sure the events are in the right temporal order
|
||||||
const executeTimes = getTimestamps(executeEvents);
|
const executeTimes = getTimestamps(executeEvents);
|
||||||
const executeActionTimes = getTimestamps(executeActionEvents);
|
const executeActionTimes = getTimestamps(executeActionEvents);
|
||||||
const newInstanceTimes = getTimestamps(newInstanceEvents);
|
const newInstanceTimes = getTimestamps(newInstanceEvents);
|
||||||
const resolvedInstanceTimes = getTimestamps(resolvedInstanceEvents);
|
const recoveredInstanceTimes = getTimestamps(recoveredInstanceEvents);
|
||||||
|
|
||||||
expect(executeTimes[0] < newInstanceTimes[0]).to.be(true);
|
expect(executeTimes[0] < newInstanceTimes[0]).to.be(true);
|
||||||
expect(executeTimes[1] <= newInstanceTimes[0]).to.be(true);
|
expect(executeTimes[1] <= newInstanceTimes[0]).to.be(true);
|
||||||
expect(executeTimes[2] > newInstanceTimes[0]).to.be(true);
|
expect(executeTimes[2] > newInstanceTimes[0]).to.be(true);
|
||||||
expect(executeTimes[1] <= executeActionTimes[0]).to.be(true);
|
expect(executeTimes[1] <= executeActionTimes[0]).to.be(true);
|
||||||
expect(executeTimes[2] > executeActionTimes[0]).to.be(true);
|
expect(executeTimes[2] > executeActionTimes[0]).to.be(true);
|
||||||
expect(resolvedInstanceTimes[0] > newInstanceTimes[0]).to.be(true);
|
expect(recoveredInstanceTimes[0] > newInstanceTimes[0]).to.be(true);
|
||||||
|
|
||||||
// validate each event
|
// validate each event
|
||||||
let executeCount = 0;
|
let executeCount = 0;
|
||||||
|
@ -136,8 +136,8 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
|
||||||
case 'new-instance':
|
case 'new-instance':
|
||||||
validateInstanceEvent(event, `created new instance: 'instance'`);
|
validateInstanceEvent(event, `created new instance: 'instance'`);
|
||||||
break;
|
break;
|
||||||
case 'resolved-instance':
|
case 'recovered-instance':
|
||||||
validateInstanceEvent(event, `resolved instance: 'instance'`);
|
validateInstanceEvent(event, `recovered instance: 'instance'`);
|
||||||
break;
|
break;
|
||||||
case 'active-instance':
|
case 'active-instance':
|
||||||
validateInstanceEvent(event, `active instance: 'instance' in actionGroup: 'default'`);
|
validateInstanceEvent(event, `active instance: 'instance' in actionGroup: 'default'`);
|
||||||
|
|
|
@ -216,7 +216,7 @@ export default function createGetAlertInstanceSummaryTests({ getService }: FtrPr
|
||||||
|
|
||||||
await alertUtils.muteInstance(createdAlert.id, 'instanceC');
|
await alertUtils.muteInstance(createdAlert.id, 'instanceC');
|
||||||
await alertUtils.muteInstance(createdAlert.id, 'instanceD');
|
await alertUtils.muteInstance(createdAlert.id, 'instanceD');
|
||||||
await waitForEvents(createdAlert.id, ['new-instance', 'resolved-instance']);
|
await waitForEvents(createdAlert.id, ['new-instance', 'recovered-instance']);
|
||||||
const response = await supertest.get(
|
const response = await supertest.get(
|
||||||
`${getUrlPrefix(Spaces.space1.id)}/api/alerts/alert/${createdAlert.id}/_instance_summary`
|
`${getUrlPrefix(Spaces.space1.id)}/api/alerts/alert/${createdAlert.id}/_instance_summary`
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
|
||||||
expect(fixtureAlertType).to.eql({
|
expect(fixtureAlertType).to.eql({
|
||||||
actionGroups: [
|
actionGroups: [
|
||||||
{ id: 'default', name: 'Default' },
|
{ id: 'default', name: 'Default' },
|
||||||
{ id: 'resolved', name: 'Resolved' },
|
{ id: 'recovered', name: 'Recovered' },
|
||||||
],
|
],
|
||||||
defaultActionGroupId: 'default',
|
defaultActionGroupId: 'default',
|
||||||
id: 'test.noop',
|
id: 'test.noop',
|
||||||
|
|
Loading…
Reference in a new issue