[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 { 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];
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 } },
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'];
|
||||
|
|
|
@ -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 [
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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',
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -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 () => {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -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'`);
|
||||
|
|
|
@ -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`
|
||||
);
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in a new issue