Revert the Revert of "[Alerting] renames Resolved action group to Recovered (#84123)" (#84662)

Reapplies the #84123 PR:
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:
Gidi Meir Morris 2020-12-01 17:30:05 +00:00 committed by GitHub
parent 68decb8352
commit 6da6db28ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 152 additions and 95 deletions

View file

@ -6,13 +6,13 @@
import { i18n } from '@kbn/i18n';
import { ActionGroup } from './alert_type';
export const ResolvedActionGroup: ActionGroup = {
id: 'resolved',
name: i18n.translate('xpack.alerts.builtinActionGroups.resolved', {
defaultMessage: 'Resolved',
export const RecoveredActionGroup: ActionGroup = {
id: 'recovered',
name: i18n.translate('xpack.alerts.builtinActionGroups.recovered', {
defaultMessage: 'Recovered',
}),
};
export function getBuiltinActionGroups(): ActionGroup[] {
return [ResolvedActionGroup];
return [RecoveredActionGroup];
}

View file

@ -105,8 +105,8 @@ describe('register()', () => {
name: 'Default',
},
{
id: 'resolved',
name: 'Resolved',
id: 'recovered',
name: 'Recovered',
},
],
defaultActionGroupId: 'default',
@ -117,7 +117,7 @@ describe('register()', () => {
expect(() => registry.register(alertType)).toThrowError(
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",
},
Object {
"id": "resolved",
"name": "Resolved",
"id": "recovered",
"name": "Recovered",
},
],
"actionVariables": Object {
@ -287,8 +287,8 @@ describe('list()', () => {
"name": "Test Action Group",
},
Object {
"id": "resolved",
"name": "Resolved",
"id": "recovered",
"name": "Recovered",
},
],
"actionVariables": Object {

View file

@ -122,7 +122,7 @@ describe('getAlertInstanceSummary()', () => {
.addActiveInstance('instance-previously-active', 'action group B')
.advanceTime(10000)
.addExecute()
.addResolvedInstance('instance-previously-active')
.addRecoveredInstance('instance-previously-active')
.addActiveInstance('instance-currently-active', 'action group A')
.getEvents();
const eventsResult = {

View file

@ -6,7 +6,7 @@
import { SanitizedAlert, AlertInstanceSummary } from '../types';
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';
const ONE_HOUR_IN_MILLIS = 60 * 60 * 1000;
@ -189,7 +189,43 @@ describe('alertInstanceSummaryFromEventLog', () => {
.addActiveInstance('instance-1', 'action group A')
.advanceTime(10000)
.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();
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
@ -224,7 +260,7 @@ describe('alertInstanceSummaryFromEventLog', () => {
.addActiveInstance('instance-1', 'action group A')
.advanceTime(10000)
.addExecute()
.addResolvedInstance('instance-1')
.addRecoveredInstance('instance-1')
.getEvents();
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
@ -406,7 +442,7 @@ describe('alertInstanceSummaryFromEventLog', () => {
.advanceTime(10000)
.addExecute()
.addActiveInstance('instance-1', 'action group A')
.addResolvedInstance('instance-2')
.addRecoveredInstance('instance-2')
.getEvents();
const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({
@ -451,7 +487,7 @@ describe('alertInstanceSummaryFromEventLog', () => {
.advanceTime(10000)
.addExecute()
.addActiveInstance('instance-1', 'action group A')
.addResolvedInstance('instance-2')
.addRecoveredInstance('instance-2')
.advanceTime(10000)
.addExecute()
.addActiveInstance('instance-1', 'action group B')
@ -561,12 +597,24 @@ export class EventsFactory {
return this;
}
addResolvedInstance(instanceId: string): EventsFactory {
addRecoveredInstance(instanceId: string): EventsFactory {
this.events.push({
'@timestamp': this.date,
event: {
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 } },
});

View file

@ -6,7 +6,7 @@
import { SanitizedAlert, AlertInstanceSummary, AlertInstanceStatus } from '../types';
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 {
alert: SanitizedAlert;
@ -80,7 +80,8 @@ export function alertInstanceSummaryFromEventLog(
status.status = 'Active';
status.actionGroupId = event?.kibana?.alerting?.action_group_id;
break;
case EVENT_LOG_ACTIONS.resolvedInstance:
case LEGACY_EVENT_LOG_ACTIONS.resolvedInstance:
case EVENT_LOG_ACTIONS.recoveredInstance:
status.status = 'OK';
status.activeStartDate = undefined;
status.actionGroupId = undefined;

View file

@ -82,9 +82,12 @@ export const EVENT_LOG_ACTIONS = {
execute: 'execute',
executeAction: 'execute-action',
newInstance: 'new-instance',
resolvedInstance: 'resolved-instance',
recoveredInstance: 'recovered-instance',
activeInstance: 'active-instance',
};
export const LEGACY_EVENT_LOG_ACTIONS = {
resolvedInstance: 'resolved-instance',
};
export interface PluginSetupContract {
registerType: AlertTypeRegistry['register'];

View file

@ -26,12 +26,12 @@ import { alertsMock, alertsClientMock } from '../mocks';
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
import { IEventLogger } from '../../../event_log/server';
import { SavedObjectsErrorHelpers } from '../../../../../src/core/server';
import { Alert, ResolvedActionGroup } from '../../common';
import { Alert, RecoveredActionGroup } from '../../common';
import { omit } from 'lodash';
const alertType = {
id: 'test',
name: 'My test alert',
actionGroups: [{ id: 'default', name: 'Default' }, ResolvedActionGroup],
actionGroups: [{ id: 'default', name: 'Default' }, RecoveredActionGroup],
defaultActionGroupId: 'default',
executor: jest.fn(),
producer: 'alerts',
@ -114,7 +114,7 @@ describe('Task Runner', () => {
},
},
{
group: ResolvedActionGroup.id,
group: RecoveredActionGroup.id,
id: '2',
actionTypeId: 'action',
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.isActionExecutable.mockReturnValue(true);
@ -650,7 +650,7 @@ describe('Task Runner', () => {
Array [
Object {
"event": Object {
"action": "resolved-instance",
"action": "recovered-instance",
},
"kibana": 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 [

View file

@ -39,7 +39,7 @@ import { IEvent, IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '../../../event_l
import { isAlertSavedObjectNotFoundError } from '../lib/is_alert_not_found_error';
import { AlertsClient } from '../alerts_client';
import { partiallyUpdateAlert } from '../saved_objects';
import { ResolvedActionGroup } from '../../common';
import { RecoveredActionGroup } from '../../common';
const FALLBACK_RETRY_INTERVAL = '5m';
@ -219,7 +219,7 @@ export class TaskRunner {
alertInstance.hasScheduledActions()
);
generateNewAndResolvedInstanceEvents({
generateNewAndRecoveredInstanceEvents({
eventLogger,
originalAlertInstances,
currentAlertInstances: instancesWithScheduledActions,
@ -229,7 +229,7 @@ export class TaskRunner {
});
if (!muteAll) {
scheduleActionsForResolvedInstances(
scheduleActionsForRecoveredInstances(
alertInstances,
executionHandler,
originalAlertInstances,
@ -436,7 +436,7 @@ export class TaskRunner {
}
}
interface GenerateNewAndResolvedInstanceEventsParams {
interface GenerateNewAndRecoveredInstanceEventsParams {
eventLogger: IEventLogger;
originalAlertInstances: Dictionary<AlertInstance>;
currentAlertInstances: Dictionary<AlertInstance>;
@ -445,18 +445,20 @@ interface GenerateNewAndResolvedInstanceEventsParams {
namespace: string | undefined;
}
function generateNewAndResolvedInstanceEvents(params: GenerateNewAndResolvedInstanceEventsParams) {
function generateNewAndRecoveredInstanceEvents(
params: GenerateNewAndRecoveredInstanceEventsParams
) {
const { eventLogger, alertId, namespace, currentAlertInstances, originalAlertInstances } = params;
const originalAlertInstanceIds = Object.keys(originalAlertInstances);
const currentAlertInstanceIds = Object.keys(currentAlertInstances);
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 message = `${params.alertLabel} resolved instance: '${id}'`;
logInstanceEvent(id, EVENT_LOG_ACTIONS.resolvedInstance, message, actionGroup);
const message = `${params.alertLabel} instance '${id}' has recovered`;
logInstanceEvent(id, EVENT_LOG_ACTIONS.recoveredInstance, message, actionGroup);
}
for (const id of newIds) {
@ -496,7 +498,7 @@ function generateNewAndResolvedInstanceEvents(params: GenerateNewAndResolvedInst
}
}
function scheduleActionsForResolvedInstances(
function scheduleActionsForRecoveredInstances(
alertInstancesMap: Record<string, AlertInstance>,
executionHandler: ReturnType<typeof createExecutionHandler>,
originalAlertInstances: Record<string, AlertInstance>,
@ -505,22 +507,22 @@ function scheduleActionsForResolvedInstances(
) {
const currentAlertInstanceIds = Object.keys(currentAlertInstances);
const originalAlertInstanceIds = Object.keys(originalAlertInstances);
const resolvedIds = without(
const recoveredIds = without(
originalAlertInstanceIds,
...currentAlertInstanceIds,
...mutedInstanceIds
);
for (const id of resolvedIds) {
for (const id of recoveredIds) {
const instance = alertInstancesMap[id];
instance.updateLastScheduledActions(ResolvedActionGroup.id);
instance.updateLastScheduledActions(RecoveredActionGroup.id);
instance.unscheduleActions();
executionHandler({
actionGroup: ResolvedActionGroup.id,
actionGroup: RecoveredActionGroup.id,
context: {},
state: {},
alertInstanceId: id,
});
instance.scheduleActions(ResolvedActionGroup.id);
instance.scheduleActions(RecoveredActionGroup.id);
}
}

View file

@ -9,7 +9,7 @@ import moment from 'moment';
import { getCustomMetricLabel } from '../../../../common/formatters/get_custom_metric_label';
import { toMetricOpt } from '../../../../common/snapshot_metric_i18n';
import { AlertStates, InventoryMetricConditions } from './types';
import { ResolvedActionGroup } from '../../../../../alerts/common';
import { RecoveredActionGroup } from '../../../../../alerts/common';
import { AlertExecutorOptions } from '../../../../../alerts/server';
import { InventoryItemType, SnapshotMetricType } from '../../../../common/inventory_models/types';
import { InfraBackendLibs } from '../../infra_types';
@ -103,7 +103,7 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
}
if (reason) {
const actionGroupId =
nextState === AlertStates.OK ? ResolvedActionGroup.id : FIRED_ACTIONS.id;
nextState === AlertStates.OK ? RecoveredActionGroup.id : FIRED_ACTIONS.id;
alertInstance.scheduleActions(actionGroupId, {
group: item,
alertState: stateToAlertMessage[nextState],

View file

@ -6,7 +6,7 @@
import { createMetricThresholdExecutor, FIRED_ACTIONS } from './metric_threshold_executor';
import { Comparator, AlertStates } from './types';
import * as mocks from './test_mocks';
import { ResolvedActionGroup } from '../../../../../alerts/common';
import { RecoveredActionGroup } from '../../../../../alerts/common';
import { AlertExecutorOptions } from '../../../../../alerts/server';
import {
alertsMock,
@ -367,7 +367,7 @@ describe('The metric threshold alert type', () => {
expect(mostRecentAction(instanceID).id).toBe(FIRED_ACTIONS.id);
expect(getState(instanceID).alertState).toBe(AlertStates.ALERT);
await execute([2]);
expect(mostRecentAction(instanceID).id).toBe(ResolvedActionGroup.id);
expect(mostRecentAction(instanceID).id).toBe(RecoveredActionGroup.id);
expect(getState(instanceID).alertState).toBe(AlertStates.OK);
});
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(getState(instanceID).alertState).toBe(AlertStates.ALERT);
await execute([2]);
expect(mostRecentAction(instanceID).id).toBe(ResolvedActionGroup.id);
expect(mostRecentAction(instanceID).id).toBe(RecoveredActionGroup.id);
expect(getState(instanceID).alertState).toBe(AlertStates.OK);
});
});

View file

@ -6,7 +6,7 @@
import { first, last } from 'lodash';
import { i18n } from '@kbn/i18n';
import moment from 'moment';
import { ResolvedActionGroup } from '../../../../../alerts/common';
import { RecoveredActionGroup } from '../../../../../alerts/common';
import { AlertExecutorOptions } from '../../../../../alerts/server';
import { InfraBackendLibs } from '../../infra_types';
import {
@ -89,7 +89,7 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) =>
const firstResult = first(alertResults);
const timestamp = (firstResult && firstResult[group].timestamp) ?? moment().toISOString();
const actionGroupId =
nextState === AlertStates.OK ? ResolvedActionGroup.id : FIRED_ACTIONS.id;
nextState === AlertStates.OK ? RecoveredActionGroup.id : FIRED_ACTIONS.id;
alertInstance.scheduleActions(actionGroupId, {
group,
alertState: stateToAlertMessage[nextState],

View file

@ -16,10 +16,10 @@ export const routeToConnectors = `/connectors`;
export const routeToAlerts = `/alerts`;
export const routeToAlertDetails = `/alert/:alertId`;
export const resolvedActionGroupMessage = i18n.translate(
'xpack.triggersActionsUI.sections.actionForm.ResolvedMessage',
export const recoveredActionGroupMessage = i18n.translate(
'xpack.triggersActionsUI.sections.actionForm.RecoveredMessage',
{
defaultMessage: 'Resolved',
defaultMessage: 'Recovered',
}
);

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ResolvedActionGroup } from '../../../../alerts/common';
import { RecoveredActionGroup } from '../../../../alerts/common';
import { AlertProvidedActionVariables } from './action_variables';
import { getDefaultsForActionParams } from './get_defaults_for_action_params';
@ -16,8 +16,8 @@ describe('getDefaultsForActionParams', () => {
});
});
test('pagerduty defaults for resolved action group', async () => {
expect(getDefaultsForActionParams('.pagerduty', ResolvedActionGroup.id)).toEqual({
test('pagerduty defaults for recovered action group', async () => {
expect(getDefaultsForActionParams('.pagerduty', RecoveredActionGroup.id)).toEqual({
dedupKey: `{{${AlertProvidedActionVariables.alertId}}}:{{${AlertProvidedActionVariables.alertInstanceId}}}`,
eventAction: 'resolve',
});

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { AlertActionParam, ResolvedActionGroup } from '../../../../alerts/common';
import { AlertActionParam, RecoveredActionGroup } from '../../../../alerts/common';
import { AlertProvidedActionVariables } from './action_variables';
export const getDefaultsForActionParams = (
@ -17,7 +17,7 @@ export const getDefaultsForActionParams = (
dedupKey: `{{${AlertProvidedActionVariables.alertId}}}:{{${AlertProvidedActionVariables.alertInstanceId}}}`,
eventAction: 'trigger',
};
if (actionGroupId === ResolvedActionGroup.id) {
if (actionGroupId === RecoveredActionGroup.id) {
pagerDutyDefaults.eventAction = 'resolve';
}
return pagerDutyDefaults;

View file

@ -10,8 +10,9 @@ import { act } from 'react-dom/test-utils';
import { actionTypeRegistryMock } from '../../action_type_registry.mock';
import { ValidationResult, Alert, AlertAction } from '../../../types';
import ActionForm from './action_form';
import { ResolvedActionGroup } from '../../../../../alerts/common';
import { RecoveredActionGroup } from '../../../../../alerts/common';
import { useKibana } from '../../../common/lib/kibana';
import { EuiScreenReaderOnly } from '@elastic/eui';
jest.mock('../../../common/lib/kibana');
jest.mock('../../lib/action_connector_api', () => ({
loadAllActions: jest.fn(),
@ -228,7 +229,7 @@ describe('action_form', () => {
}}
actionGroups={[
{ id: 'default', name: 'Default' },
{ id: 'resolved', name: 'Resolved' },
{ id: 'recovered', name: 'Recovered' },
]}
setActionGroupIdByIndex={(group: string, index: number) => {
initialAlert.actions[index].group = group;
@ -347,18 +348,18 @@ describe('action_form', () => {
"value": "default",
},
Object {
"data-test-subj": "addNewActionConnectorActionGroup-0-option-resolved",
"inputDisplay": "Resolved",
"value": "resolved",
"data-test-subj": "addNewActionConnectorActionGroup-0-option-recovered",
"inputDisplay": "Recovered",
"value": "recovered",
},
]
`);
});
it('renders selected Resolved action group', async () => {
it('renders selected Recovered action group', async () => {
const wrapper = await setup([
{
group: ResolvedActionGroup.id,
group: RecoveredActionGroup.id,
id: 'test',
actionTypeId: actionType.id,
params: {
@ -381,15 +382,17 @@ describe('action_form', () => {
"value": "default",
},
Object {
"data-test-subj": "addNewActionConnectorActionGroup-0-option-resolved",
"inputDisplay": "Resolved",
"value": "resolved",
"data-test-subj": "addNewActionConnectorActionGroup-0-option-recovered",
"inputDisplay": "Recovered",
"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 () => {

View file

@ -26,7 +26,7 @@ import {
EuiBadge,
EuiErrorBoundary,
} from '@elastic/eui';
import { AlertActionParam, ResolvedActionGroup } from '../../../../../alerts/common';
import { AlertActionParam, RecoveredActionGroup } from '../../../../../alerts/common';
import {
IErrorObject,
AlertAction,
@ -40,7 +40,7 @@ import { checkActionFormActionTypeEnabled } from '../../lib/check_action_type_en
import { hasSaveActionsCapability } from '../../lib/capabilities';
import { ActionAccordionFormProps } from './action_form';
import { transformActionVariables } from '../../lib/action_variables';
import { resolvedActionGroupMessage } from '../../constants';
import { recoveredActionGroupMessage } from '../../constants';
import { useKibana } from '../../../common/lib/kibana';
import { getDefaultsForActionParams } from '../../lib/get_defaults_for_action_params';
@ -105,8 +105,8 @@ export const ActionTypeForm = ({
useEffect(() => {
setAvailableActionVariables(getAvailableActionVariables(messageVariables, actionItem.group));
const res =
actionItem.group === ResolvedActionGroup.id
? resolvedActionGroupMessage
actionItem.group === RecoveredActionGroup.id
? recoveredActionGroupMessage
: defaultActionMessage;
setAvailableDefaultActionMessage(res);
const paramsDefaults = getDefaultsForActionParams(actionItem.actionTypeId, actionItem.group);
@ -374,7 +374,7 @@ function getAvailableActionVariables(
return [];
}
const filteredActionVariables =
actionGroup === ResolvedActionGroup.id
actionGroup === RecoveredActionGroup.id
? { params: actionVariables.params, state: actionVariables.state }
: actionVariables;

View file

@ -17,7 +17,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
const expectedNoOpType = {
actionGroups: [
{ id: 'default', name: 'Default' },
{ id: 'resolved', name: 'Resolved' },
{ id: 'recovered', name: 'Recovered' },
],
defaultActionGroupId: 'default',
id: 'test.noop',
@ -33,7 +33,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
const expectedRestrictedNoOpType = {
actionGroups: [
{ id: 'default', name: 'Default' },
{ id: 'resolved', name: 'Resolved' },
{ id: 'recovered', name: 'Recovered' },
],
defaultActionGroupId: 'default',
id: 'test.restricted-noop',

View file

@ -6,7 +6,7 @@
import expect from '@kbn/expect';
import { Response as SupertestResponse } from 'supertest';
import { ResolvedActionGroup } from '../../../../../plugins/alerts/common';
import { RecoveredActionGroup } from '../../../../../plugins/alerts/common';
import { Space } from '../../../common/types';
import { FtrProviderContext } from '../../../common/ftr_provider_context';
import {
@ -137,7 +137,7 @@ instanceStateValue: true
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 { body: createdAction } = await supertestWithoutAuth
@ -174,12 +174,12 @@ instanceStateValue: true
params: {},
},
{
group: ResolvedActionGroup.id,
group: RecoveredActionGroup.id,
id: indexRecordActionId,
params: {
index: ES_TEST_INDEX_NAME,
reference,
message: 'Resolved message',
message: 'Recovered message',
},
},
],
@ -194,10 +194,10 @@ instanceStateValue: true
await esTestIndexTool.waitForDocs('action:test.index-record', reference)
)[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 reference = alertUtils.generateReference();
@ -237,12 +237,12 @@ instanceStateValue: true
params: {},
},
{
group: ResolvedActionGroup.id,
group: RecoveredActionGroup.id,
id: indexRecordActionId,
params: {
index: ES_TEST_INDEX_NAME,
reference,
message: 'Resolved message',
message: 'Recovered message',
},
},
],

View file

@ -78,7 +78,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
'execute-action',
'new-instance',
'active-instance',
'resolved-instance',
'recovered-instance',
],
});
});
@ -87,25 +87,25 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
const executeEvents = getEventsByAction(events, 'execute');
const executeActionEvents = getEventsByAction(events, 'execute-action');
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(executeActionEvents.length).to.be(2);
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
const executeTimes = getTimestamps(executeEvents);
const executeActionTimes = getTimestamps(executeActionEvents);
const newInstanceTimes = getTimestamps(newInstanceEvents);
const resolvedInstanceTimes = getTimestamps(resolvedInstanceEvents);
const recoveredInstanceTimes = getTimestamps(recoveredInstanceEvents);
expect(executeTimes[0] < newInstanceTimes[0]).to.be(true);
expect(executeTimes[1] <= newInstanceTimes[0]).to.be(true);
expect(executeTimes[2] > newInstanceTimes[0]).to.be(true);
expect(executeTimes[1] <= 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
let executeCount = 0;
@ -136,8 +136,8 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
case 'new-instance':
validateInstanceEvent(event, `created new instance: 'instance'`);
break;
case 'resolved-instance':
validateInstanceEvent(event, `resolved instance: 'instance'`);
case 'recovered-instance':
validateInstanceEvent(event, `recovered instance: 'instance'`);
break;
case 'active-instance':
validateInstanceEvent(event, `active instance: 'instance' in actionGroup: 'default'`);

View file

@ -216,7 +216,7 @@ export default function createGetAlertInstanceSummaryTests({ getService }: FtrPr
await alertUtils.muteInstance(createdAlert.id, 'instanceC');
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(
`${getUrlPrefix(Spaces.space1.id)}/api/alerts/alert/${createdAlert.id}/_instance_summary`
);

View file

@ -25,7 +25,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
expect(fixtureAlertType).to.eql({
actionGroups: [
{ id: 'default', name: 'Default' },
{ id: 'resolved', name: 'Resolved' },
{ id: 'recovered', name: 'Recovered' },
],
defaultActionGroupId: 'default',
id: 'test.noop',