Revert "[Alerting] Enforces typing of Alert's ActionGroups (#86761)"

This reverts commit 76b8c491ee.
This commit is contained in:
Jonathan Budzenski 2021-01-05 13:24:59 -06:00
parent 7ed089c50b
commit 051be28c69
69 changed files with 328 additions and 1006 deletions

View file

@ -10,16 +10,15 @@ export const ALERTING_EXAMPLE_APP_ID = 'AlertingExample';
// always firing
export const DEFAULT_INSTANCES_TO_GENERATE = 5;
export interface AlwaysFiringThresholds {
small?: number;
medium?: number;
large?: number;
}
export interface AlwaysFiringParams extends AlertTypeParams {
instances?: number;
thresholds?: AlwaysFiringThresholds;
thresholds?: {
small?: number;
medium?: number;
large?: number;
};
}
export type AlwaysFiringActionGroupIds = keyof AlwaysFiringThresholds;
export type AlwaysFiringActionGroupIds = keyof AlwaysFiringParams['thresholds'];
// Astros
export enum Craft {

View file

@ -133,10 +133,8 @@ export const AlwaysFiringExpression: React.FunctionComponent<
};
interface TShirtSelectorProps {
actionGroup?: ActionGroupWithCondition<number, AlwaysFiringActionGroupIds>;
setTShirtThreshold: (
actionGroup: ActionGroupWithCondition<number, AlwaysFiringActionGroupIds>
) => void;
actionGroup?: ActionGroupWithCondition<number>;
setTShirtThreshold: (actionGroup: ActionGroupWithCondition<number>) => void;
}
const TShirtSelector = ({ actionGroup, setTShirtThreshold }: TShirtSelectorProps) => {
const [isOpen, setIsOpen] = useState(false);

View file

@ -11,7 +11,6 @@ import {
DEFAULT_INSTANCES_TO_GENERATE,
ALERTING_EXAMPLE_APP_ID,
AlwaysFiringParams,
AlwaysFiringActionGroupIds,
} from '../../common/constants';
type ActionGroups = 'small' | 'medium' | 'large';
@ -40,8 +39,7 @@ export const alertType: AlertType<
AlwaysFiringParams,
{ count?: number },
{ triggerdOnCycle: number },
never,
AlwaysFiringActionGroupIds
never
> = {
id: 'example.always-firing',
name: 'Always firing',

View file

@ -41,10 +41,7 @@ function getCraftFilter(craft: string) {
export const alertType: AlertType<
{ outerSpaceCapacity: number; craft: string; op: string },
{ peopleInSpace: number },
{ craft: string },
never,
'default',
'hasLandedBackOnEarth'
{ craft: string }
> = {
id: 'example.people-in-space',
name: 'People In Space Right Now',

View file

@ -142,41 +142,8 @@ This example receives server and threshold as parameters. It will read the CPU u
```typescript
import { schema } from '@kbn/config-schema';
import {
Alert,
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext
} from 'x-pack/plugins/alerts/common';
...
interface MyAlertTypeParams extends AlertTypeParams {
server: string;
threshold: number;
}
interface MyAlertTypeState extends AlertTypeState {
lastChecked: number;
}
interface MyAlertTypeInstanceState extends AlertInstanceState {
cpuUsage: number;
}
interface MyAlertTypeInstanceContext extends AlertInstanceContext {
server: string;
hasCpuUsageIncreased: boolean;
}
type MyAlertTypeActionGroups = 'default' | 'warning';
const myAlertType: AlertType<
MyAlertTypeParams,
MyAlertTypeState,
MyAlertTypeInstanceState,
MyAlertTypeInstanceContext,
MyAlertTypeActionGroups
> = {
server.newPlatform.setup.plugins.alerts.registerType({
id: 'my-alert-type',
name: 'My alert type',
validate: {
@ -213,7 +180,7 @@ const myAlertType: AlertType<
services,
params,
state,
}: AlertExecutorOptions<MyAlertTypeParams, MyAlertTypeState, MyAlertTypeInstanceState, MyAlertTypeInstanceContext, MyAlertTypeActionGroups>) {
}: AlertExecutorOptions) {
// Let's assume params is { server: 'server_1', threshold: 0.8 }
const { server, threshold } = params;
@ -252,9 +219,7 @@ const myAlertType: AlertType<
};
},
producer: 'alerting',
};
server.newPlatform.setup.plugins.alerts.registerType(myAlertType);
});
```
This example only receives threshold as a parameter. It will read the CPU usage of all the servers and schedule individual actions if the reading for a server is greater than the threshold. This is a better implementation than above as only one query is performed for all the servers instead of one query per server.

View file

@ -5,29 +5,19 @@
*/
import { LicenseType } from '../../licensing/common/types';
import { RecoveredActionGroupId, DefaultActionGroupId } from './builtin_action_groups';
export interface AlertType<
ActionGroupIds extends Exclude<string, RecoveredActionGroupId> = DefaultActionGroupId,
RecoveryActionGroupId extends string = RecoveredActionGroupId
> {
export interface AlertType {
id: string;
name: string;
actionGroups: Array<ActionGroup<ActionGroupIds>>;
recoveryActionGroup: ActionGroup<RecoveryActionGroupId>;
actionGroups: ActionGroup[];
recoveryActionGroup: ActionGroup;
actionVariables: string[];
defaultActionGroupId: ActionGroupIds;
defaultActionGroupId: ActionGroup['id'];
producer: string;
minimumLicenseRequired: LicenseType;
}
export interface ActionGroup<ActionGroupIds extends string> {
id: ActionGroupIds;
export interface ActionGroup {
id: string;
name: string;
}
export type ActionGroupIdsOf<T> = T extends ActionGroup<infer groups>
? groups
: T extends Readonly<ActionGroup<infer groups>>
? groups
: never;

View file

@ -6,27 +6,13 @@
import { i18n } from '@kbn/i18n';
import { ActionGroup } from './alert_type';
export type DefaultActionGroupId = 'default';
export type RecoveredActionGroupId = typeof RecoveredActionGroup['id'];
export const RecoveredActionGroup: Readonly<ActionGroup<'recovered'>> = Object.freeze({
export const RecoveredActionGroup: Readonly<ActionGroup> = {
id: 'recovered',
name: i18n.translate('xpack.alerts.builtinActionGroups.recovered', {
defaultMessage: 'Recovered',
}),
});
};
export type ReservedActionGroups<RecoveryActionGroupId extends string> =
| RecoveryActionGroupId
| RecoveredActionGroupId;
export type WithoutReservedActionGroups<
ActionGroupIds extends string,
RecoveryActionGroupId extends string
> = ActionGroupIds extends ReservedActionGroups<RecoveryActionGroupId> ? never : ActionGroupIds;
export function getBuiltinActionGroups<RecoveryActionGroupId extends string>(
customRecoveryGroup?: ActionGroup<RecoveryActionGroupId>
): [ActionGroup<ReservedActionGroups<RecoveryActionGroupId>>] {
return [customRecoveryGroup ?? RecoveredActionGroup];
export function getBuiltinActionGroups(customRecoveryGroup?: ActionGroup): ActionGroup[] {
return [customRecoveryGroup ?? Object.freeze(RecoveredActionGroup)];
}

View file

@ -6,7 +6,6 @@
import sinon from 'sinon';
import { AlertInstance } from './alert_instance';
import { AlertInstanceState, AlertInstanceContext, DefaultActionGroupId } from '../../common';
let clock: sinon.SinonFakeTimers;
@ -18,20 +17,12 @@ afterAll(() => clock.restore());
describe('hasScheduledActions()', () => {
test('defaults to false', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
expect(alertInstance.hasScheduledActions()).toEqual(false);
});
test('returns true when scheduleActions is called', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
alertInstance.scheduleActions('default');
expect(alertInstance.hasScheduledActions()).toEqual(true);
});
@ -39,11 +30,7 @@ describe('hasScheduledActions()', () => {
describe('isThrottled', () => {
test(`should throttle when group didn't change and throttle period is still active`, () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -57,11 +44,7 @@ describe('isThrottled', () => {
});
test(`shouldn't throttle when group didn't change and throttle period expired`, () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -75,7 +58,7 @@ describe('isThrottled', () => {
});
test(`shouldn't throttle when group changes`, () => {
const alertInstance = new AlertInstance<never, never, 'default' | 'other-group'>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -91,20 +74,12 @@ describe('isThrottled', () => {
describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
test('should be false if no last scheduled and nothing scheduled', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(false);
});
test('should be false if group does not change', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -117,11 +92,7 @@ describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
});
test('should be false if group and subgroup does not change', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -135,11 +106,7 @@ describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
});
test('should be false if group does not change and subgroup goes from undefined to defined', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -152,11 +119,7 @@ describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
});
test('should be false if group does not change and subgroup goes from defined to undefined', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -170,17 +133,13 @@ describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
});
test('should be true if no last scheduled and has scheduled action', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
alertInstance.scheduleActions('default');
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(true);
});
test('should be true if group does change', () => {
const alertInstance = new AlertInstance<never, never, 'default' | 'penguin'>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -193,7 +152,7 @@ describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
});
test('should be true if group does change and subgroup does change', () => {
const alertInstance = new AlertInstance<never, never, 'default' | 'penguin'>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -207,11 +166,7 @@ describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
});
test('should be true if group does not change and subgroup does change', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
@ -227,22 +182,14 @@ describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
describe('getScheduledActionOptions()', () => {
test('defaults to undefined', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
expect(alertInstance.getScheduledActionOptions()).toBeUndefined();
});
});
describe('unscheduleActions()', () => {
test('makes hasScheduledActions() return false', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
alertInstance.scheduleActions('default');
expect(alertInstance.hasScheduledActions()).toEqual(true);
alertInstance.unscheduleActions();
@ -250,11 +197,7 @@ describe('unscheduleActions()', () => {
});
test('makes getScheduledActionOptions() return undefined', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
alertInstance.scheduleActions('default');
expect(alertInstance.getScheduledActionOptions()).toEqual({
actionGroup: 'default',
@ -269,22 +212,14 @@ describe('unscheduleActions()', () => {
describe('getState()', () => {
test('returns state passed to constructor', () => {
const state = { foo: true };
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({ state });
const alertInstance = new AlertInstance({ state });
expect(alertInstance.getState()).toEqual(state);
});
});
describe('scheduleActions()', () => {
test('makes hasScheduledActions() return true', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -298,11 +233,7 @@ describe('scheduleActions()', () => {
});
test('makes isThrottled() return true when throttled', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -316,11 +247,7 @@ describe('scheduleActions()', () => {
});
test('make isThrottled() return false when throttled expired', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -335,11 +262,7 @@ describe('scheduleActions()', () => {
});
test('makes getScheduledActionOptions() return given options', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({ state: { foo: true }, meta: {} });
const alertInstance = new AlertInstance({ state: { foo: true }, meta: {} });
alertInstance.replaceState({ otherField: true }).scheduleActions('default', { field: true });
expect(alertInstance.getScheduledActionOptions()).toEqual({
actionGroup: 'default',
@ -349,11 +272,7 @@ describe('scheduleActions()', () => {
});
test('cannot schdule for execution twice', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
alertInstance.scheduleActions('default', { field: true });
expect(() =>
alertInstance.scheduleActions('default', { field: false })
@ -365,11 +284,7 @@ describe('scheduleActions()', () => {
describe('scheduleActionsWithSubGroup()', () => {
test('makes hasScheduledActions() return true', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -385,11 +300,7 @@ describe('scheduleActionsWithSubGroup()', () => {
});
test('makes isThrottled() return true when throttled and subgroup is the same', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -406,11 +317,7 @@ describe('scheduleActionsWithSubGroup()', () => {
});
test('makes isThrottled() return true when throttled and last schedule had no subgroup', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -426,11 +333,7 @@ describe('scheduleActionsWithSubGroup()', () => {
});
test('makes isThrottled() return false when throttled and subgroup is the different', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -447,11 +350,7 @@ describe('scheduleActionsWithSubGroup()', () => {
});
test('make isThrottled() return false when throttled expired', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -468,11 +367,7 @@ describe('scheduleActionsWithSubGroup()', () => {
});
test('makes getScheduledActionOptions() return given options', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({ state: { foo: true }, meta: {} });
const alertInstance = new AlertInstance({ state: { foo: true }, meta: {} });
alertInstance
.replaceState({ otherField: true })
.scheduleActionsWithSubGroup('default', 'subgroup', { field: true });
@ -485,11 +380,7 @@ describe('scheduleActionsWithSubGroup()', () => {
});
test('cannot schdule for execution twice', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
alertInstance.scheduleActionsWithSubGroup('default', 'subgroup', { field: true });
expect(() =>
alertInstance.scheduleActionsWithSubGroup('default', 'subgroup', { field: false })
@ -499,11 +390,7 @@ describe('scheduleActionsWithSubGroup()', () => {
});
test('cannot schdule for execution twice with different subgroups', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
alertInstance.scheduleActionsWithSubGroup('default', 'subgroup', { field: true });
expect(() =>
alertInstance.scheduleActionsWithSubGroup('default', 'subgroup', { field: false })
@ -513,11 +400,7 @@ describe('scheduleActionsWithSubGroup()', () => {
});
test('cannot schdule for execution twice whether there are subgroups', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>();
const alertInstance = new AlertInstance();
alertInstance.scheduleActions('default', { field: true });
expect(() =>
alertInstance.scheduleActionsWithSubGroup('default', 'subgroup', { field: false })
@ -529,11 +412,7 @@ describe('scheduleActionsWithSubGroup()', () => {
describe('replaceState()', () => {
test('replaces previous state', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({ state: { foo: true } });
const alertInstance = new AlertInstance({ state: { foo: true } });
alertInstance.replaceState({ bar: true });
expect(alertInstance.getState()).toEqual({ bar: true });
alertInstance.replaceState({ baz: true });
@ -543,11 +422,7 @@ describe('replaceState()', () => {
describe('updateLastScheduledActions()', () => {
test('replaces previous lastScheduledActions', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({ meta: {} });
const alertInstance = new AlertInstance({ meta: {} });
alertInstance.updateLastScheduledActions('default');
expect(alertInstance.toJSON()).toEqual({
state: {},
@ -563,11 +438,7 @@ describe('updateLastScheduledActions()', () => {
describe('toJSON', () => {
test('only serializes state and meta', () => {
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>({
const alertInstance = new AlertInstance({
state: { foo: true },
meta: {
lastScheduledActions: {
@ -593,11 +464,7 @@ describe('toRaw', () => {
},
},
};
const alertInstance = new AlertInstance<
AlertInstanceState,
AlertInstanceContext,
DefaultActionGroupId
>(raw);
const alertInstance = new AlertInstance(raw);
expect(alertInstance.toRaw()).toEqual(raw);
});
});

View file

@ -9,17 +9,15 @@ import {
RawAlertInstance,
rawAlertInstance,
AlertInstanceContext,
DefaultActionGroupId,
} from '../../common';
import { parseDuration } from '../lib';
interface ScheduledExecutionOptions<
State extends AlertInstanceState,
Context extends AlertInstanceContext,
ActionGroupIds extends string = DefaultActionGroupId
Context extends AlertInstanceContext
> {
actionGroup: ActionGroupIds;
actionGroup: string;
subgroup?: string;
context: Context;
state: State;
@ -27,19 +25,17 @@ interface ScheduledExecutionOptions<
export type PublicAlertInstance<
State extends AlertInstanceState = AlertInstanceState,
Context extends AlertInstanceContext = AlertInstanceContext,
ActionGroupIds extends string = DefaultActionGroupId
Context extends AlertInstanceContext = AlertInstanceContext
> = Pick<
AlertInstance<State, Context, ActionGroupIds>,
AlertInstance<State, Context>,
'getState' | 'replaceState' | 'scheduleActions' | 'scheduleActionsWithSubGroup'
>;
export class AlertInstance<
State extends AlertInstanceState = AlertInstanceState,
Context extends AlertInstanceContext = AlertInstanceContext,
ActionGroupIds extends string = never
Context extends AlertInstanceContext = AlertInstanceContext
> {
private scheduledExecutionOptions?: ScheduledExecutionOptions<State, Context, ActionGroupIds>;
private scheduledExecutionOptions?: ScheduledExecutionOptions<State, Context>;
private meta: AlertInstanceMeta;
private state: State;
@ -101,14 +97,14 @@ export class AlertInstance<
private scheduledActionGroupIsUnchanged(
lastScheduledActions: NonNullable<AlertInstanceMeta['lastScheduledActions']>,
scheduledExecutionOptions: ScheduledExecutionOptions<State, Context, ActionGroupIds>
scheduledExecutionOptions: ScheduledExecutionOptions<State, Context>
) {
return lastScheduledActions.group === scheduledExecutionOptions.actionGroup;
}
private scheduledActionSubgroupIsUnchanged(
lastScheduledActions: NonNullable<AlertInstanceMeta['lastScheduledActions']>,
scheduledExecutionOptions: ScheduledExecutionOptions<State, Context, ActionGroupIds>
scheduledExecutionOptions: ScheduledExecutionOptions<State, Context>
) {
return lastScheduledActions.subgroup && scheduledExecutionOptions.subgroup
? lastScheduledActions.subgroup === scheduledExecutionOptions.subgroup
@ -132,7 +128,7 @@ export class AlertInstance<
return this.state;
}
scheduleActions(actionGroup: ActionGroupIds, context: Context = {} as Context) {
scheduleActions(actionGroup: string, context: Context = {} as Context) {
this.ensureHasNoScheduledActions();
this.scheduledExecutionOptions = {
actionGroup,
@ -143,7 +139,7 @@ export class AlertInstance<
}
scheduleActionsWithSubGroup(
actionGroup: ActionGroupIds,
actionGroup: string,
subgroup: string,
context: Context = {} as Context
) {
@ -168,7 +164,7 @@ export class AlertInstance<
return this;
}
updateLastScheduledActions(group: ActionGroupIds, subgroup?: string) {
updateLastScheduledActions(group: string, subgroup?: string) {
this.meta.lastScheduledActions = { group, subgroup, date: new Date() };
}

View file

@ -9,12 +9,11 @@ import { AlertInstance } from './alert_instance';
export function createAlertInstanceFactory<
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string
>(alertInstances: Record<string, AlertInstance<InstanceState, InstanceContext, ActionGroupIds>>) {
return (id: string): AlertInstance<InstanceState, InstanceContext, ActionGroupIds> => {
InstanceContext extends AlertInstanceContext
>(alertInstances: Record<string, AlertInstance<InstanceState, InstanceContext>>) {
return (id: string): AlertInstance<InstanceState, InstanceContext> => {
if (!alertInstances[id]) {
alertInstances[id] = new AlertInstance<InstanceState, InstanceContext, ActionGroupIds>();
alertInstances[id] = new AlertInstance<InstanceState, InstanceContext>();
}
return alertInstances[id];

View file

@ -6,7 +6,7 @@
import { TaskRunnerFactory } from './task_runner';
import { AlertTypeRegistry, ConstructorOptions } from './alert_type_registry';
import { ActionGroup, AlertType } from './types';
import { AlertType } from './types';
import { taskManagerMock } from '../../task_manager/server/mocks';
import { ILicenseState } from './lib/license_state';
import { licenseStateMock } from './lib/license_state.mock';
@ -55,7 +55,7 @@ describe('has()', () => {
describe('register()', () => {
test('throws if AlertType Id contains invalid characters', () => {
const alertType: AlertType<never, never, never, never, 'default'> = {
const alertType: AlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@ -87,7 +87,7 @@ describe('register()', () => {
});
test('throws if AlertType Id isnt a string', () => {
const alertType: AlertType<never, never, never, never, 'default'> = {
const alertType: AlertType = {
id: (123 as unknown) as string,
name: 'Test',
actionGroups: [
@ -109,7 +109,7 @@ describe('register()', () => {
});
test('throws if AlertType action groups contains reserved group id', () => {
const alertType: AlertType<never, never, never, never, 'default' | 'NotReserved'> = {
const alertType: AlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@ -117,14 +117,10 @@ describe('register()', () => {
id: 'default',
name: 'Default',
},
/**
* The type system will ensure you can't use the `recovered` action group
* but we also want to ensure this at runtime
*/
({
{
id: 'recovered',
name: 'Recovered',
} as unknown) as ActionGroup<'NotReserved'>,
},
],
defaultActionGroupId: 'default',
minimumLicenseRequired: 'basic',
@ -141,7 +137,7 @@ describe('register()', () => {
});
test('allows an AlertType to specify a custom recovery group', () => {
const alertType: AlertType<never, never, never, never, 'default', 'backToAwesome'> = {
const alertType: AlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@ -176,14 +172,7 @@ describe('register()', () => {
});
test('throws if the custom recovery group is contained in the AlertType action groups', () => {
const alertType: AlertType<
never,
never,
never,
never,
'default' | 'backToAwesome',
'backToAwesome'
> = {
const alertType: AlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@ -215,7 +204,7 @@ describe('register()', () => {
});
test('registers the executor with the task manager', () => {
const alertType: AlertType<never, never, never, never, 'default'> = {
const alertType: AlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@ -245,7 +234,7 @@ describe('register()', () => {
});
test('shallow clones the given alert type', () => {
const alertType: AlertType<never, never, never, never, 'default'> = {
const alertType: AlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@ -486,12 +475,8 @@ describe('ensureAlertTypeEnabled', () => {
});
});
function alertTypeWithVariables<ActionGroupIds extends string>(
id: ActionGroupIds,
context: string,
state: string
): AlertType<never, never, never, never, ActionGroupIds> {
const baseAlert: AlertType<never, never, never, never, ActionGroupIds> = {
function alertTypeWithVariables(id: string, context: string, state: string): AlertType {
const baseAlert: AlertType = {
id,
name: `${id}-name`,
actionGroups: [],

View file

@ -19,12 +19,7 @@ import {
AlertInstanceState,
AlertInstanceContext,
} from './types';
import {
RecoveredActionGroup,
getBuiltinActionGroups,
RecoveredActionGroupId,
ActionGroup,
} from '../common';
import { RecoveredActionGroup, getBuiltinActionGroups } from '../common';
import { ILicenseState } from './lib/license_state';
import { getAlertTypeFeatureUsageName } from './lib/get_alert_type_feature_usage_name';
@ -74,36 +69,15 @@ export type NormalizedAlertType<
Params extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
> = {
actionGroups: Array<ActionGroup<ActionGroupIds | RecoveryActionGroupId>>;
} & Omit<
AlertType<Params, State, InstanceState, InstanceContext, ActionGroupIds, RecoveryActionGroupId>,
'recoveryActionGroup' | 'actionGroups'
> &
Pick<
Required<
AlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>
>,
'recoveryActionGroup'
>;
InstanceContext extends AlertInstanceContext
> = Omit<AlertType<Params, State, InstanceState, InstanceContext>, 'recoveryActionGroup'> &
Pick<Required<AlertType<Params, State, InstanceState, InstanceContext>>, 'recoveryActionGroup'>;
export type UntypedNormalizedAlertType = NormalizedAlertType<
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string,
string
AlertInstanceContext
>;
export class AlertTypeRegistry {
@ -132,19 +106,8 @@ export class AlertTypeRegistry {
Params extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
alertType: AlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>
) {
InstanceContext extends AlertInstanceContext
>(alertType: AlertType<Params, State, InstanceState, InstanceContext>) {
if (this.has(alertType.id)) {
throw new Error(
i18n.translate('xpack.alerts.alertTypeRegistry.register.duplicateAlertTypeError', {
@ -161,28 +124,18 @@ export class AlertTypeRegistry {
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
InstanceContext
>(alertType);
this.alertTypes.set(
alertIdSchema.validate(alertType.id),
/** stripping the typing is required in order to store the AlertTypes in a Map */
(normalizedAlertType as unknown) as UntypedNormalizedAlertType
normalizedAlertType as UntypedNormalizedAlertType
);
this.taskManager.registerTaskDefinitions({
[`alerting:${alertType.id}`]: {
title: alertType.name,
createTaskRunner: (context: RunContext) =>
this.taskRunnerFactory.create<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId | RecoveredActionGroupId
>(normalizedAlertType, context),
this.taskRunnerFactory.create(normalizedAlertType as UntypedNormalizedAlertType, context),
},
});
// No need to notify usage on basic alert types
@ -198,19 +151,8 @@ export class AlertTypeRegistry {
Params extends AlertTypeParams = AlertTypeParams,
State extends AlertTypeState = AlertTypeState,
InstanceState extends AlertInstanceState = AlertInstanceState,
InstanceContext extends AlertInstanceContext = AlertInstanceContext,
ActionGroupIds extends string = string,
RecoveryActionGroupId extends string = string
>(
id: string
): NormalizedAlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
> {
InstanceContext extends AlertInstanceContext = AlertInstanceContext
>(id: string): NormalizedAlertType<Params, State, InstanceState, InstanceContext> {
if (!this.has(id)) {
throw Boom.badRequest(
i18n.translate('xpack.alerts.alertTypeRegistry.get.missingAlertTypeError', {
@ -221,18 +163,11 @@ export class AlertTypeRegistry {
})
);
}
/**
* When we store the AlertTypes in the Map we strip the typing.
* This means that returning a typed AlertType in `get` is an inherently
* unsafe operation. Down casting to `unknown` is the only way to achieve this.
*/
return (this.alertTypes.get(id)! as unknown) as NormalizedAlertType<
return this.alertTypes.get(id)! as NormalizedAlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
InstanceContext
>;
}
@ -282,31 +217,15 @@ function augmentActionGroupsWithReserved<
Params extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
InstanceContext extends AlertInstanceContext
>(
alertType: AlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>
): NormalizedAlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveredActionGroupId | RecoveryActionGroupId
> {
alertType: AlertType<Params, State, InstanceState, InstanceContext>
): NormalizedAlertType<Params, State, InstanceState, InstanceContext> {
const reservedActionGroups = getBuiltinActionGroups(alertType.recoveryActionGroup);
const { id, actionGroups, recoveryActionGroup } = alertType;
const activeActionGroups = new Set<string>(actionGroups.map((item) => item.id));
const intersectingReservedActionGroups = intersection<string>(
const activeActionGroups = new Set(actionGroups.map((item) => item.id));
const intersectingReservedActionGroups = intersection(
[...activeActionGroups.values()],
reservedActionGroups.map((item) => item.id)
);

View file

@ -16,7 +16,6 @@ export {
ActionVariable,
AlertType,
ActionGroup,
ActionGroupIdsOf,
AlertingPlugin,
AlertExecutorOptions,
AlertActionParams,

View file

@ -56,7 +56,7 @@ describe('getLicenseCheckForAlertType', () => {
let license: Subject<ILicense>;
let licenseState: ILicenseState;
const mockNotifyUsage = jest.fn();
const alertType: AlertType<never, never, never, never, 'default', 'recovered'> = {
const alertType: AlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@ -190,7 +190,7 @@ describe('ensureLicenseForAlertType()', () => {
let license: Subject<ILicense>;
let licenseState: ILicenseState;
const mockNotifyUsage = jest.fn();
const alertType: AlertType<never, never, never, never, string, string> = {
const alertType: AlertType = {
id: 'test',
name: 'Test',
actionGroups: [

View file

@ -13,13 +13,7 @@ import { LicensingPluginStart } from '../../../licensing/server';
import { ILicense, LicenseType } from '../../../licensing/common/types';
import { PLUGIN } from '../constants/plugin';
import { getAlertTypeFeatureUsageName } from './get_alert_type_feature_usage_name';
import {
AlertType,
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
} from '../types';
import { AlertType } from '../types';
import { AlertTypeDisabledError } from './errors/alert_type_disabled';
export type ILicenseState = PublicMethodsOf<LicenseState>;
@ -136,23 +130,7 @@ export class LicenseState {
}
}
public ensureLicenseForAlertType<
Params extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
alertType: AlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>
) {
public ensureLicenseForAlertType(alertType: AlertType) {
this.notifyUsage(alertType.name, alertType.minimumLicenseRequired);
const check = this.getLicenseCheckForAlertType(

View file

@ -58,7 +58,7 @@ describe('Alerting Plugin', () => {
describe('registerType()', () => {
let setup: PluginSetupContract;
const sampleAlertType: AlertType<never, never, never, never, 'default'> = {
const sampleAlertType: AlertType = {
id: 'test',
name: 'test',
minimumLicenseRequired: 'basic',

View file

@ -102,18 +102,9 @@ export interface PluginSetupContract {
Params extends AlertTypeParams = AlertTypeParams,
State extends AlertTypeState = AlertTypeState,
InstanceState extends AlertInstanceState = AlertInstanceState,
InstanceContext extends AlertInstanceContext = AlertInstanceContext,
ActionGroupIds extends string = never,
RecoveryActionGroupId extends string = never
InstanceContext extends AlertInstanceContext = AlertInstanceContext
>(
alertType: AlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>
alertType: AlertType<Params, State, InstanceState, InstanceContext>
): void;
}
@ -282,19 +273,8 @@ export class AlertingPlugin {
Params extends AlertTypeParams = AlertTypeParams,
State extends AlertTypeState = AlertTypeState,
InstanceState extends AlertInstanceState = AlertInstanceState,
InstanceContext extends AlertInstanceContext = AlertInstanceContext,
ActionGroupIds extends string = never,
RecoveryActionGroupId extends string = never
>(
alertType: AlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>
) {
InstanceContext extends AlertInstanceContext = AlertInstanceContext
>(alertType: AlertType<Params, State, InstanceState, InstanceContext>) {
if (!(alertType.minimumLicenseRequired in LICENSE_TYPE)) {
throw new Error(`"${alertType.minimumLicenseRequired}" is not a valid license type`);
}

View file

@ -15,7 +15,7 @@ import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
import { KibanaRequest } from 'kibana/server';
import { asSavedObjectExecutionSource } from '../../../actions/server';
import { InjectActionParamsOpts } from './inject_action_params';
import { NormalizedAlertType } from '../alert_type_registry';
import { UntypedNormalizedAlertType } from '../alert_type_registry';
import {
AlertTypeParams,
AlertTypeState,
@ -27,14 +27,7 @@ jest.mock('./inject_action_params', () => ({
injectActionParams: jest.fn(),
}));
const alertType: NormalizedAlertType<
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
'default' | 'other-group',
'recovered'
> = {
const alertType: UntypedNormalizedAlertType = {
id: 'test',
name: 'Test',
actionGroups: [
@ -60,9 +53,7 @@ const createExecutionHandlerParams: jest.Mocked<
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
'default' | 'other-group',
'recovered'
AlertInstanceContext
>
> = {
actionsPlugin: mockActionsPlugin,
@ -357,9 +348,7 @@ test('state attribute gets parameterized', async () => {
test(`logs an error when action group isn't part of actionGroups available for the alertType`, async () => {
const executionHandler = createExecutionHandler(createExecutionHandlerParams);
const result = await executionHandler({
// we have to trick the compiler as this is an invalid type and this test checks whether we
// enforce this at runtime as well as compile time
actionGroup: 'invalid-group' as 'default' | 'other-group',
actionGroup: 'invalid-group',
context: {},
state: {},
alertInstanceId: '2',

View file

@ -27,9 +27,7 @@ export interface CreateExecutionHandlerOptions<
Params extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
InstanceContext extends AlertInstanceContext
> {
alertId: string;
alertName: string;
@ -38,39 +36,26 @@ export interface CreateExecutionHandlerOptions<
actions: AlertAction[];
spaceId: string;
apiKey: RawAlert['apiKey'];
alertType: NormalizedAlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>;
alertType: NormalizedAlertType<Params, State, InstanceState, InstanceContext>;
logger: Logger;
eventLogger: IEventLogger;
request: KibanaRequest;
alertParams: AlertTypeParams;
}
interface ExecutionHandlerOptions<ActionGroupIds extends string> {
actionGroup: ActionGroupIds;
interface ExecutionHandlerOptions {
actionGroup: string;
actionSubgroup?: string;
alertInstanceId: string;
context: AlertInstanceContext;
state: AlertInstanceState;
}
export type ExecutionHandler<ActionGroupIds extends string> = (
options: ExecutionHandlerOptions<ActionGroupIds>
) => Promise<void>;
export function createExecutionHandler<
Params extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
InstanceContext extends AlertInstanceContext
>({
logger,
alertId,
@ -84,14 +69,7 @@ export function createExecutionHandler<
eventLogger,
request,
alertParams,
}: CreateExecutionHandlerOptions<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>): ExecutionHandler<ActionGroupIds | RecoveryActionGroupId> {
}: CreateExecutionHandlerOptions<Params, State, InstanceState, InstanceContext>) {
const alertTypeActionGroups = new Map(
alertType.actionGroups.map((actionGroup) => [actionGroup.id, actionGroup.name])
);
@ -101,7 +79,7 @@ export function createExecutionHandler<
context,
state,
alertInstanceId,
}: ExecutionHandlerOptions<ActionGroupIds | RecoveryActionGroupId>) => {
}: ExecutionHandlerOptions) => {
if (!alertTypeActionGroups.has(actionGroup)) {
logger.error(`Invalid action group "${actionGroup}" for alert "${alertType.id}".`);
return;

View file

@ -266,8 +266,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices
.alertInstanceFactory('1')
@ -427,8 +426,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
@ -544,8 +542,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
executorServices.alertInstanceFactory('2').scheduleActions('default');
@ -598,8 +595,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
@ -700,8 +696,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
@ -748,8 +743,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices
.alertInstanceFactory('1')
@ -804,8 +798,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
@ -980,8 +973,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
@ -1088,8 +1080,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
@ -1187,8 +1178,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
@ -1457,8 +1447,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
throw new Error('OMG');
}
@ -1833,8 +1822,7 @@ describe('Task Runner', () => {
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
string
AlertInstanceContext
>) => {
throw new Error('OMG');
}

View file

@ -10,7 +10,7 @@ import { addSpaceIdToPath } from '../../../spaces/server';
import { Logger, KibanaRequest } from '../../../../../src/core/server';
import { TaskRunnerContext } from './task_runner_factory';
import { ConcreteTaskInstance, throwUnrecoverableError } from '../../../task_manager/server';
import { createExecutionHandler, ExecutionHandler } from './create_execution_handler';
import { createExecutionHandler } from './create_execution_handler';
import { AlertInstance, createAlertInstanceFactory } from '../alert_instance';
import {
validateAlertTypeParams,
@ -44,7 +44,6 @@ import {
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
WithoutReservedActionGroups,
} from '../../common';
import { NormalizedAlertType } from '../alert_type_registry';
@ -65,32 +64,16 @@ export class TaskRunner<
Params extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
InstanceContext extends AlertInstanceContext
> {
private context: TaskRunnerContext;
private logger: Logger;
private taskInstance: AlertTaskInstance;
private alertType: NormalizedAlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>;
private alertType: NormalizedAlertType<Params, State, InstanceState, InstanceContext>;
private readonly alertTypeRegistry: AlertTypeRegistry;
constructor(
alertType: NormalizedAlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>,
alertType: NormalizedAlertType<Params, State, InstanceState, InstanceContext>,
taskInstance: ConcreteTaskInstance,
context: TaskRunnerContext
) {
@ -161,14 +144,7 @@ export class TaskRunner<
actions: Alert<Params>['actions'],
alertParams: Params
) {
return createExecutionHandler<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>({
return createExecutionHandler({
alertId,
alertName,
tags,
@ -187,7 +163,7 @@ export class TaskRunner<
async executeAlertInstance(
alertInstanceId: string,
alertInstance: AlertInstance<InstanceState, InstanceContext>,
executionHandler: ExecutionHandler<ActionGroupIds | RecoveryActionGroupId>
executionHandler: ReturnType<typeof createExecutionHandler>
) {
const {
actionGroup,
@ -204,7 +180,7 @@ export class TaskRunner<
services: Services,
alert: SanitizedAlert<Params>,
params: Params,
executionHandler: ExecutionHandler<ActionGroupIds | RecoveryActionGroupId>,
executionHandler: ReturnType<typeof createExecutionHandler>,
spaceId: string,
event: Event
): Promise<AlertTaskState> {
@ -242,11 +218,9 @@ export class TaskRunner<
alertId,
services: {
...services,
alertInstanceFactory: createAlertInstanceFactory<
InstanceState,
InstanceContext,
WithoutReservedActionGroups<ActionGroupIds, RecoveryActionGroupId>
>(alertInstances),
alertInstanceFactory: createAlertInstanceFactory<InstanceState, InstanceContext>(
alertInstances
),
},
params,
state: alertTypeState as State,
@ -304,7 +278,7 @@ export class TaskRunner<
if (!muteAll) {
const mutedInstanceIdsSet = new Set(mutedInstanceIds);
scheduleActionsForRecoveredInstances<InstanceState, InstanceContext, RecoveryActionGroupId>({
scheduleActionsForRecoveredInstances({
recoveryActionGroup: this.alertType.recoveryActionGroup,
recoveredAlertInstances,
executionHandler,
@ -641,30 +615,20 @@ function generateNewAndRecoveredInstanceEvents<
interface ScheduleActionsForRecoveredInstancesParams<
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
RecoveryActionGroupId extends string
InstanceContext extends AlertInstanceContext
> {
logger: Logger;
recoveryActionGroup: ActionGroup<RecoveryActionGroupId>;
recoveredAlertInstances: Dictionary<
AlertInstance<InstanceState, InstanceContext, RecoveryActionGroupId>
>;
executionHandler: ExecutionHandler<RecoveryActionGroupId | RecoveryActionGroupId>;
recoveryActionGroup: ActionGroup;
recoveredAlertInstances: Dictionary<AlertInstance<InstanceState, InstanceContext>>;
executionHandler: ReturnType<typeof createExecutionHandler>;
mutedInstanceIdsSet: Set<string>;
alertLabel: string;
}
function scheduleActionsForRecoveredInstances<
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
RecoveryActionGroupId extends string
>(
params: ScheduleActionsForRecoveredInstancesParams<
InstanceState,
InstanceContext,
RecoveryActionGroupId
>
) {
InstanceContext extends AlertInstanceContext
>(params: ScheduleActionsForRecoveredInstancesParams<InstanceState, InstanceContext>) {
const {
logger,
recoveryActionGroup,
@ -696,31 +660,18 @@ function scheduleActionsForRecoveredInstances<
interface LogActiveAndRecoveredInstancesParams<
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
InstanceContext extends AlertInstanceContext
> {
logger: Logger;
activeAlertInstances: Dictionary<AlertInstance<InstanceState, InstanceContext, ActionGroupIds>>;
recoveredAlertInstances: Dictionary<
AlertInstance<InstanceState, InstanceContext, RecoveryActionGroupId>
>;
activeAlertInstances: Dictionary<AlertInstance<InstanceState, InstanceContext>>;
recoveredAlertInstances: Dictionary<AlertInstance<InstanceState, InstanceContext>>;
alertLabel: string;
}
function logActiveAndRecoveredInstances<
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
params: LogActiveAndRecoveredInstancesParams<
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>
) {
InstanceContext extends AlertInstanceContext
>(params: LogActiveAndRecoveredInstancesParams<InstanceState, InstanceContext>) {
const { logger, activeAlertInstances, recoveredAlertInstances, alertLabel } = params;
const activeInstanceIds = Object.keys(activeAlertInstances);
const recoveredInstanceIds = Object.keys(recoveredAlertInstances);

View file

@ -13,19 +13,11 @@ import {
import { RunContext } from '../../../task_manager/server';
import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server';
import { PluginStartContract as ActionsPluginStartContract } from '../../../actions/server';
import {
AlertTypeParams,
AlertTypeRegistry,
GetServicesFunction,
SpaceIdToNamespaceFunction,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
} from '../types';
import { AlertTypeRegistry, GetServicesFunction, SpaceIdToNamespaceFunction } from '../types';
import { TaskRunner } from './task_runner';
import { IEventLogger } from '../../../event_log/server';
import { AlertsClient } from '../alerts_client';
import { NormalizedAlertType } from '../alert_type_registry';
import { UntypedNormalizedAlertType } from '../alert_type_registry';
export interface TaskRunnerContext {
logger: Logger;
@ -52,35 +44,11 @@ export class TaskRunnerFactory {
this.taskRunnerContext = taskRunnerContext;
}
public create<
Params extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
alertType: NormalizedAlertType<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>,
{ taskInstance }: RunContext
) {
public create(alertType: UntypedNormalizedAlertType, { taskInstance }: RunContext) {
if (!this.isInitialized) {
throw new Error('TaskRunnerFactory not initialized');
}
return new TaskRunner<
Params,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>(alertType, taskInstance, this.taskRunnerContext!);
return new TaskRunner(alertType, taskInstance, this.taskRunnerContext!);
}
}

View file

@ -29,7 +29,6 @@ import {
AlertExecutionStatusErrorReasons,
AlertsHealth,
AlertNotifyWhenType,
WithoutReservedActionGroups,
} from '../common';
import { LicenseType } from '../../licensing/server';
@ -59,25 +58,21 @@ export interface Services {
export interface AlertServices<
InstanceState extends AlertInstanceState = AlertInstanceState,
InstanceContext extends AlertInstanceContext = AlertInstanceContext,
ActionGroupIds extends string = never
InstanceContext extends AlertInstanceContext = AlertInstanceContext
> extends Services {
alertInstanceFactory: (
id: string
) => PublicAlertInstance<InstanceState, InstanceContext, ActionGroupIds>;
alertInstanceFactory: (id: string) => PublicAlertInstance<InstanceState, InstanceContext>;
}
export interface AlertExecutorOptions<
Params extends AlertTypeParams = never,
State extends AlertTypeState = never,
InstanceState extends AlertInstanceState = never,
InstanceContext extends AlertInstanceContext = never,
ActionGroupIds extends string = never
InstanceContext extends AlertInstanceContext = never
> {
alertId: string;
startedAt: Date;
previousStartedAt: Date | null;
services: AlertServices<InstanceState, InstanceContext, ActionGroupIds>;
services: AlertServices<InstanceState, InstanceContext>;
params: Params;
state: State;
spaceId: string;
@ -97,10 +92,9 @@ export type ExecutorType<
Params extends AlertTypeParams = never,
State extends AlertTypeState = never,
InstanceState extends AlertInstanceState = never,
InstanceContext extends AlertInstanceContext = never,
ActionGroupIds extends string = never
InstanceContext extends AlertInstanceContext = never
> = (
options: AlertExecutorOptions<Params, State, InstanceState, InstanceContext, ActionGroupIds>
options: AlertExecutorOptions<Params, State, InstanceState, InstanceContext>
) => Promise<State | void>;
export interface AlertTypeParamsValidator<Params extends AlertTypeParams> {
@ -110,29 +104,17 @@ export interface AlertType<
Params extends AlertTypeParams = never,
State extends AlertTypeState = never,
InstanceState extends AlertInstanceState = never,
InstanceContext extends AlertInstanceContext = never,
ActionGroupIds extends string = never,
RecoveryActionGroupId extends string = never
InstanceContext extends AlertInstanceContext = never
> {
id: string;
name: string;
validate?: {
params?: AlertTypeParamsValidator<Params>;
};
actionGroups: Array<ActionGroup<ActionGroupIds>>;
defaultActionGroupId: ActionGroup<ActionGroupIds>['id'];
recoveryActionGroup?: ActionGroup<RecoveryActionGroupId>;
executor: ExecutorType<
Params,
State,
InstanceState,
InstanceContext,
/**
* Ensure that the reserved ActionGroups (such as `Recovered`) are not
* available for scheduling in the Executor
*/
WithoutReservedActionGroups<ActionGroupIds, RecoveryActionGroupId>
>;
actionGroups: ActionGroup[];
defaultActionGroupId: ActionGroup['id'];
recoveryActionGroup?: ActionGroup;
executor: ExecutorType<Params, State, InstanceState, InstanceContext>;
producer: string;
actionVariables?: {
context?: ActionVariable[];

View file

@ -6,7 +6,6 @@
import { i18n } from '@kbn/i18n';
import { ValuesType } from 'utility-types';
import { ActionGroup } from '../../alerts/common';
import { ANOMALY_SEVERITY, ANOMALY_THRESHOLD } from '../../ml/common';
export enum AlertType {
@ -16,31 +15,20 @@ export enum AlertType {
TransactionDurationAnomaly = 'apm.transaction_duration_anomaly',
}
export const THRESHOLD_MET_GROUP_ID = 'threshold_met';
export type ThresholdMetActionGroupId = typeof THRESHOLD_MET_GROUP_ID;
const THRESHOLD_MET_GROUP: ActionGroup<ThresholdMetActionGroupId> = {
id: THRESHOLD_MET_GROUP_ID,
const THRESHOLD_MET_GROUP = {
id: 'threshold_met',
name: i18n.translate('xpack.apm.a.thresholdMet', {
defaultMessage: 'Threshold met',
}),
};
export const ALERT_TYPES_CONFIG: Record<
AlertType,
{
name: string;
actionGroups: Array<ActionGroup<ThresholdMetActionGroupId>>;
defaultActionGroupId: ThresholdMetActionGroupId;
minimumLicenseRequired: string;
producer: string;
}
> = {
export const ALERT_TYPES_CONFIG = {
[AlertType.ErrorCount]: {
name: i18n.translate('xpack.apm.errorCountAlert.name', {
defaultMessage: 'Error count threshold',
}),
actionGroups: [THRESHOLD_MET_GROUP],
defaultActionGroupId: THRESHOLD_MET_GROUP_ID,
defaultActionGroupId: 'threshold_met',
minimumLicenseRequired: 'basic',
producer: 'apm',
},
@ -49,7 +37,7 @@ export const ALERT_TYPES_CONFIG: Record<
defaultMessage: 'Transaction duration threshold',
}),
actionGroups: [THRESHOLD_MET_GROUP],
defaultActionGroupId: THRESHOLD_MET_GROUP_ID,
defaultActionGroupId: 'threshold_met',
minimumLicenseRequired: 'basic',
producer: 'apm',
},
@ -58,7 +46,7 @@ export const ALERT_TYPES_CONFIG: Record<
defaultMessage: 'Transaction duration anomaly',
}),
actionGroups: [THRESHOLD_MET_GROUP],
defaultActionGroupId: THRESHOLD_MET_GROUP_ID,
defaultActionGroupId: 'threshold_met',
minimumLicenseRequired: 'basic',
producer: 'apm',
},
@ -67,7 +55,7 @@ export const ALERT_TYPES_CONFIG: Record<
defaultMessage: 'Transaction error rate threshold',
}),
actionGroups: [THRESHOLD_MET_GROUP],
defaultActionGroupId: THRESHOLD_MET_GROUP_ID,
defaultActionGroupId: 'threshold_met',
minimumLicenseRequired: 'basic',
producer: 'apm',
},

View file

@ -4,23 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ThresholdMetActionGroupId } from '../../../common/alert_types';
import {
ESSearchRequest,
ESSearchResponse,
} from '../../../../../typings/elasticsearch';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../alerts/server';
import { AlertServices } from '../../../../alerts/server';
export function alertingEsClient<TParams extends ESSearchRequest>(
services: AlertServices<
AlertInstanceState,
AlertInstanceContext,
ThresholdMetActionGroupId
>,
services: AlertServices,
params: TParams
): Promise<ESSearchResponse<unknown, TParams>> {
return services.callCluster('search', {

View file

@ -4,22 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { schema, TypeOf } from '@kbn/config-schema';
import { schema } from '@kbn/config-schema';
import { isEmpty } from 'lodash';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import { APMConfig } from '../..';
import {
AlertingPlugin,
AlertInstanceContext,
AlertInstanceState,
AlertTypeState,
} from '../../../../alerts/server';
import {
AlertType,
ALERT_TYPES_CONFIG,
ThresholdMetActionGroupId,
} from '../../../common/alert_types';
import { AlertingPlugin } from '../../../../alerts/server';
import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types';
import {
PROCESSOR_EVENT,
SERVICE_ENVIRONMENT,
@ -50,13 +41,7 @@ export function registerErrorCountAlertType({
alerts,
config$,
}: RegisterAlertParams) {
alerts.registerType<
TypeOf<typeof paramsSchema>,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
ThresholdMetActionGroupId
>({
alerts.registerType({
id: AlertType.ErrorCount,
name: alertTypeConfig.name,
actionGroups: alertTypeConfig.actionGroups,

View file

@ -10,7 +10,6 @@ import { getCustomMetricLabel } from '../../../../common/formatters/get_custom_m
import { toMetricOpt } from '../../../../common/snapshot_metric_i18n';
import { AlertStates, InventoryMetricConditions } from './types';
import {
ActionGroup,
AlertInstanceContext,
AlertInstanceState,
RecoveredActionGroup,
@ -28,7 +27,6 @@ import {
stateToAlertMessage,
} from '../common/messages';
import { evaluateCondition } from './evaluate_condition';
import { InventoryMetricThresholdAllowedActionGroups } from './register_inventory_metric_threshold_alert_type';
interface InventoryMetricThresholdParams {
criteria: InventoryMetricConditions[];
@ -48,8 +46,7 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
Record<string, any>,
Record<string, any>,
AlertInstanceState,
AlertInstanceContext,
InventoryMetricThresholdAllowedActionGroups
AlertInstanceContext
>) => {
const {
criteria,
@ -118,25 +115,18 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
}
if (reason) {
const actionGroupId =
nextState === AlertStates.OK ? RecoveredActionGroup.id : FIRED_ACTIONS_ID;
alertInstance.scheduleActions(
/**
* TODO: We're lying to the compiler here as explicitly calling `scheduleActions` on
* the RecoveredActionGroup isn't allowed
*/
(actionGroupId as unknown) as InventoryMetricThresholdAllowedActionGroups,
{
group: item,
alertState: stateToAlertMessage[nextState],
reason,
timestamp: moment().toISOString(),
value: mapToConditionsLookup(results, (result) =>
formatMetric(result[item].metric, result[item].currentValue)
),
threshold: mapToConditionsLookup(criteria, (c) => c.threshold),
metric: mapToConditionsLookup(criteria, (c) => c.metric),
}
);
nextState === AlertStates.OK ? RecoveredActionGroup.id : FIRED_ACTIONS.id;
alertInstance.scheduleActions(actionGroupId, {
group: item,
alertState: stateToAlertMessage[nextState],
reason,
timestamp: moment().toISOString(),
value: mapToConditionsLookup(results, (result) =>
formatMetric(result[item].metric, result[item].currentValue)
),
threshold: mapToConditionsLookup(criteria, (c) => c.threshold),
metric: mapToConditionsLookup(criteria, (c) => c.metric),
});
}
alertInstance.replaceState({
@ -170,9 +160,8 @@ const mapToConditionsLookup = (
{}
);
export const FIRED_ACTIONS_ID = 'metrics.invenotry_threshold.fired';
export const FIRED_ACTIONS: ActionGroup<typeof FIRED_ACTIONS_ID> = {
id: FIRED_ACTIONS_ID,
export const FIRED_ACTIONS = {
id: 'metrics.invenotry_threshold.fired',
name: i18n.translate('xpack.infra.metrics.alerting.inventory.threshold.fired', {
defaultMessage: 'Fired',
}),

View file

@ -9,7 +9,6 @@ import { AlertType, AlertInstanceState, AlertInstanceContext } from '../../../..
import {
createInventoryMetricThresholdExecutor,
FIRED_ACTIONS,
FIRED_ACTIONS_ID,
} from './inventory_metric_threshold_executor';
import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, Comparator } from './types';
import { InfraBackendLibs } from '../../infra_types';
@ -23,7 +22,6 @@ import {
metricActionVariableDescription,
thresholdActionVariableDescription,
} from '../common/messages';
import { RecoveredActionGroupId } from '../../../../../alerts/common';
const condition = schema.object({
threshold: schema.arrayOf(schema.number()),
@ -42,8 +40,6 @@ const condition = schema.object({
),
});
export type InventoryMetricThresholdAllowedActionGroups = typeof FIRED_ACTIONS_ID;
export const registerMetricInventoryThresholdAlertType = (
libs: InfraBackendLibs
): AlertType<
@ -53,9 +49,7 @@ export const registerMetricInventoryThresholdAlertType = (
Record<string, any>,
Record<string, any>,
AlertInstanceState,
AlertInstanceContext,
InventoryMetricThresholdAllowedActionGroups,
RecoveredActionGroupId
AlertInstanceContext
> => ({
id: METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID,
name: i18n.translate('xpack.infra.metrics.inventory.alertName', {
@ -75,7 +69,7 @@ export const registerMetricInventoryThresholdAlertType = (
{ unknowns: 'allow' }
),
},
defaultActionGroupId: FIRED_ACTIONS_ID,
defaultActionGroupId: FIRED_ACTIONS.id,
actionGroups: [FIRED_ACTIONS],
producer: 'infrastructure',
minimumLicenseRequired: 'basic',

View file

@ -13,8 +13,6 @@ import {
AlertTypeState,
AlertInstanceContext,
AlertInstanceState,
ActionGroup,
ActionGroupIdsOf,
} from '../../../../../alerts/server';
import {
AlertStates,
@ -39,18 +37,12 @@ import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds';
import { decodeOrThrow } from '../../../../common/runtime_types';
import { UNGROUPED_FACTORY_KEY } from '../common/utils';
type LogThresholdActionGroups = ActionGroupIdsOf<typeof FIRED_ACTIONS>;
type LogThresholdAlertServices = AlertServices<
AlertInstanceState,
AlertInstanceContext,
LogThresholdActionGroups
>;
type LogThresholdAlertServices = AlertServices<AlertInstanceState, AlertInstanceContext>;
type LogThresholdAlertExecutorOptions = AlertExecutorOptions<
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
LogThresholdActionGroups
AlertInstanceContext
>;
const COMPOSITE_GROUP_SIZE = 40;
@ -352,9 +344,9 @@ export const processGroupByRatioResults = (
};
type AlertInstanceUpdater = (
alertInstance: AlertInstance<AlertInstanceState, AlertInstanceContext, LogThresholdActionGroups>,
alertInstance: AlertInstance,
state: AlertStates,
actions?: Array<{ actionGroup: LogThresholdActionGroups; context: AlertInstanceContext }>
actions?: Array<{ actionGroup: string; context: AlertInstanceContext }>
) => void;
export const updateAlertInstance: AlertInstanceUpdater = (alertInstance, state, actions) => {
@ -661,9 +653,8 @@ const createConditionsMessageForCriteria = (criteria: CountCriteria) => {
// When the Alerting plugin implements support for multiple action groups, add additional
// action groups here to send different messages, e.g. a recovery notification
export const LogsThresholdFiredActionGroupId = 'logs.threshold.fired';
export const FIRED_ACTIONS: ActionGroup<'logs.threshold.fired'> = {
id: LogsThresholdFiredActionGroupId,
export const FIRED_ACTIONS = {
id: 'logs.threshold.fired',
name: i18n.translate('xpack.infra.logs.alerting.threshold.fired', {
defaultMessage: 'Fired',
}),

View file

@ -4,14 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
import {
PluginSetupContract,
AlertTypeParams,
AlertTypeState,
AlertInstanceContext,
AlertInstanceState,
ActionGroupIdsOf,
} from '../../../../../alerts/server';
import { PluginSetupContract } from '../../../../../alerts/server';
import { createLogThresholdExecutor, FIRED_ACTIONS } from './log_threshold_executor';
import {
LOG_DOCUMENT_COUNT_ALERT_TYPE_ID,
@ -86,13 +79,7 @@ export async function registerLogThresholdAlertType(
);
}
alertingPlugin.registerType<
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
ActionGroupIdsOf<typeof FIRED_ACTIONS>
>({
alertingPlugin.registerType({
id: LOG_DOCUMENT_COUNT_ALERT_TYPE_ID,
name: i18n.translate('xpack.infra.logs.alertName', {
defaultMessage: 'Log threshold',

View file

@ -10,7 +10,6 @@ import {
AlertInstanceState,
AlertInstanceContext,
AlertExecutorOptions,
ActionGroupIdsOf,
} from '../../../../../alerts/server';
import { METRIC_EXPLORER_AGGREGATIONS } from '../../../../common/http_api/metrics_explorer';
import { createMetricThresholdExecutor, FIRED_ACTIONS } from './metric_threshold_executor';
@ -34,8 +33,7 @@ export type MetricThresholdAlertType = AlertType<
Record<string, any>,
Record<string, any>,
AlertInstanceState,
AlertInstanceContext,
ActionGroupIdsOf<typeof FIRED_ACTIONS>
AlertInstanceContext
>;
export type MetricThresholdAlertExecutorOptions = AlertExecutorOptions<
/**
@ -44,8 +42,7 @@ export type MetricThresholdAlertExecutorOptions = AlertExecutorOptions<
Record<string, any>,
Record<string, any>,
AlertInstanceState,
AlertInstanceContext,
ActionGroupIdsOf<typeof FIRED_ACTIONS>
AlertInstanceContext
>;
export function registerMetricThresholdAlertType(libs: InfraBackendLibs): MetricThresholdAlertType {

View file

@ -93,7 +93,7 @@ export class BaseAlert {
this.scopedLogger = Globals.app.getLogger(alertOptions.id!);
}
public getAlertType(): AlertType<never, never, never, never, 'default'> {
public getAlertType(): AlertType {
const { id, name, actionVariables } = this.alertOptions;
return {
id,
@ -108,11 +108,8 @@ export class BaseAlert {
],
defaultActionGroupId: 'default',
minimumLicenseRequired: 'basic',
executor: (
options: AlertExecutorOptions<never, never, AlertInstanceState, never, 'default'> & {
state: ExecutedState;
}
): Promise<any> => this.execute(options),
executor: (options: AlertExecutorOptions & { state: ExecutedState }): Promise<any> =>
this.execute(options),
producer: 'monitoring',
actionVariables: {
context: actionVariables,
@ -241,9 +238,7 @@ export class BaseAlert {
services,
params,
state,
}: AlertExecutorOptions<never, never, AlertInstanceState, never, 'default'> & {
state: ExecutedState;
}): Promise<any> {
}: AlertExecutorOptions & { state: ExecutedState }): Promise<any> {
this.scopedLogger.debug(
`Executing alert with params: ${JSON.stringify(params)} and state: ${JSON.stringify(state)}`
);
@ -338,7 +333,7 @@ export class BaseAlert {
protected async processData(
data: AlertData[],
clusters: AlertCluster[],
services: AlertServices<AlertInstanceState, never, 'default'>,
services: AlertServices,
state: ExecutedState
) {
const currentUTC = +new Date();
@ -392,7 +387,7 @@ export class BaseAlert {
protected async processLegacyData(
data: AlertData[],
clusters: AlertCluster[],
services: AlertServices<AlertInstanceState, never, 'default'>,
services: AlertServices,
state: ExecutedState
) {
const currentUTC = +new Date();

View file

@ -105,7 +105,7 @@ export const isNotificationAlertExecutor = (
};
export type NotificationAlertTypeDefinition = Omit<
AlertType<AlertTypeParams, AlertTypeState, AlertInstanceState, AlertInstanceContext, 'default'>,
AlertType<AlertTypeParams, AlertTypeState, AlertInstanceState, AlertInstanceContext>,
'executor'
> & {
executor: ({

View file

@ -8,11 +8,7 @@ import { flow, omit } from 'lodash/fp';
import set from 'set-value';
import { Logger } from '../../../../../../../src/core/server';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
import { RuleAlertAction } from '../../../../common/detection_engine/types';
import { RuleTypeParams, RefreshTypes } from '../types';
import { singleBulkCreate, SingleBulkCreateResponse } from './single_bulk_create';
@ -24,7 +20,7 @@ interface BulkCreateMlSignalsParams {
actions: RuleAlertAction[];
someResult: AnomalyResults;
ruleParams: RuleTypeParams;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
logger: Logger;
id: string;
signalsIndex: string;

View file

@ -12,11 +12,7 @@ import {
TimestampOverrideOrUndefined,
} from '../../../../common/detection_engine/schemas/common/schemas';
import { Logger } from '../../../../../../../src/core/server';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
import { RuleAlertAction } from '../../../../common/detection_engine/types';
import { RuleTypeParams, RefreshTypes } from '../types';
import { singleBulkCreate, SingleBulkCreateResponse } from './single_bulk_create';
@ -28,7 +24,7 @@ interface BulkCreateThresholdSignalsParams {
actions: RuleAlertAction[];
someResult: SignalSearchResponse;
ruleParams: RuleTypeParams;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
inputIndexPattern: string[];
logger: Logger;
id: string;

View file

@ -12,11 +12,7 @@ import {
} from '../../../../common/detection_engine/schemas/common/schemas';
import { singleSearchAfter } from './single_search_after';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
import { Logger } from '../../../../../../../src/core/server';
import { SignalSearchResponse } from './types';
import { BuildRuleMessage } from './rule_messages';
@ -25,7 +21,7 @@ interface FindThresholdSignalsParams {
from: string;
to: string;
inputIndexPattern: string[];
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
logger: Logger;
filter: unknown;
threshold: Threshold;

View file

@ -15,11 +15,7 @@ import {
Language,
} from '../../../../common/detection_engine/schemas/common/schemas';
import { ExceptionListItemSchema } from '../../../../../lists/common/schemas';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
import { PartialFilter } from '../types';
import { BadRequestError } from '../errors/bad_request_error';
import { QueryFilter } from './types';
@ -30,7 +26,7 @@ interface GetFilterArgs {
language: LanguageOrUndefined;
query: QueryOrUndefined;
savedId: SavedIdOrUndefined;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
index: IndexOrUndefined;
lists: ExceptionListItemSchema[];
}

View file

@ -5,14 +5,10 @@
*/
import { DEFAULT_INDEX_KEY, DEFAULT_INDEX_PATTERN } from '../../../../common/constants';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
export const getInputIndex = async (
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>,
services: AlertServices,
version: string,
inputIndex: string[] | null | undefined
): Promise<string[]> => {

View file

@ -5,9 +5,8 @@
*/
import { i18n } from '@kbn/i18n';
import { ActionGroup } from '../../../../../alerts/common';
export const siemRuleActionGroups: Array<ActionGroup<'default'>> = [
export const siemRuleActionGroups = [
{
id: 'default',
name: i18n.translate(

View file

@ -6,11 +6,7 @@
import { countBy, isEmpty, get } from 'lodash';
import { performance } from 'perf_hooks';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
import { SignalSearchResponse, BulkResponse, SignalHit, WrappedSignalHit } from './types';
import { RuleAlertAction } from '../../../../common/detection_engine/types';
import { RuleTypeParams, RefreshTypes } from '../types';
@ -23,7 +19,7 @@ import { isEventTypeSignal } from './build_event_type_signal';
interface SingleBulkCreateParams {
filteredEvents: SignalSearchResponse;
ruleParams: RuleTypeParams;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
logger: Logger;
id: string;
signalsIndex: string;
@ -226,7 +222,7 @@ export const singleBulkCreate = async ({
export const bulkInsertSignals = async (
signals: WrappedSignalHit[],
logger: Logger,
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>,
services: AlertServices,
refresh: RefreshTypes
): Promise<BulkInsertSignalsResponse> => {
// index documents after creating an ID based on the

View file

@ -5,11 +5,7 @@
*/
import { performance } from 'perf_hooks';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
import { Logger } from '../../../../../../../src/core/server';
import { SignalSearchResponse } from './types';
import { BuildRuleMessage } from './rule_messages';
@ -26,7 +22,7 @@ interface SingleSearchAfterParams {
index: string[];
from: string;
to: string;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
logger: Logger;
pageSize: number;
sortOrder?: SortOrderOrUndefined;

View file

@ -20,11 +20,7 @@ import {
ItemsPerSearch,
} from '../../../../../common/detection_engine/schemas/types/threat_mapping';
import { PartialFilter, RuleTypeParams } from '../../types';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../../alerts/server';
import { AlertServices } from '../../../../../../alerts/server';
import { ExceptionListItemSchema } from '../../../../../../lists/common/schemas';
import { ILegacyScopedClusterClient, Logger } from '../../../../../../../../src/core/server';
import { RuleAlertAction } from '../../../../../common/detection_engine/types';
@ -42,7 +38,7 @@ export interface CreateThreatSignalsOptions {
filters: PartialFilter[];
language: LanguageOrUndefined;
savedId: string | undefined;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
exceptionItems: ExceptionListItemSchema[];
gap: Duration | null;
previousStartedAt: Date | null;
@ -81,7 +77,7 @@ export interface CreateThreatSignalOptions {
filters: PartialFilter[];
language: LanguageOrUndefined;
savedId: string | undefined;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
exceptionItems: ExceptionListItemSchema[];
gap: Duration | null;
previousStartedAt: Date | null;

View file

@ -7,11 +7,7 @@
import { TimestampOverrideOrUndefined } from '../../../../common/detection_engine/schemas/common/schemas';
import { singleSearchAfter } from './single_search_after';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
import { Logger } from '../../../../../../../src/core/server';
import { SignalSearchResponse } from './types';
import { BuildRuleMessage } from './rule_messages';
@ -20,7 +16,7 @@ interface FindPreviousThresholdSignalsParams {
from: string;
to: string;
indexPattern: string[];
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
logger: Logger;
ruleId: string;
bucketByField: string;

View file

@ -10,11 +10,7 @@ import { Filter } from 'src/plugins/data/common';
import { ESFilter } from '../../../../../../typings/elasticsearch';
import { TimestampOverrideOrUndefined } from '../../../../common/detection_engine/schemas/common/schemas';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
} from '../../../../../alerts/server';
import { AlertServices } from '../../../../../alerts/server';
import { Logger } from '../../../../../../../src/core/server';
import { ThresholdQueryBucket } from './types';
import { BuildRuleMessage } from './rule_messages';
@ -24,7 +20,7 @@ interface GetThresholdBucketFiltersParams {
from: string;
to: string;
indexPattern: string[];
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
logger: Logger;
ruleId: string;
bucketByField: string;

View file

@ -141,13 +141,7 @@ export type RuleExecutorOptions = AlertExecutorOptions<
// since we are only increasing the strictness of params.
export const isAlertExecutor = (
obj: SignalRuleAlertTypeDefinition
): obj is AlertType<
RuleTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
'default'
> => {
): obj is AlertType<RuleTypeParams, AlertTypeState, AlertInstanceState, AlertInstanceContext> => {
return true;
};
@ -155,8 +149,7 @@ export type SignalRuleAlertTypeDefinition = AlertType<
RuleTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
'default'
AlertInstanceContext
>;
export interface Ancestor {
@ -231,7 +224,7 @@ export interface SearchAfterAndBulkCreateParams {
gap: moment.Duration | null;
previousStartedAt: Date | null | undefined;
ruleParams: RuleTypeParams;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
listClient: ListClient;
exceptionsList: ExceptionListItemSchema[];
logger: Logger;

View file

@ -10,12 +10,7 @@ import dateMath from '@elastic/datemath';
import { TimestampOverrideOrUndefined } from '../../../../common/detection_engine/schemas/common/schemas';
import { Logger, SavedObjectsClientContract } from '../../../../../../../src/core/server';
import {
AlertInstanceContext,
AlertInstanceState,
AlertServices,
parseDuration,
} from '../../../../../alerts/server';
import { AlertServices, parseDuration } from '../../../../../alerts/server';
import { ExceptionListClient, ListClient, ListPluginSetup } from '../../../../../lists/server';
import { ExceptionListItemSchema } from '../../../../../lists/common/schemas';
import { ListArray } from '../../../../common/detection_engine/schemas/types/lists';
@ -57,10 +52,7 @@ export const shorthandMap = {
},
};
export const checkPrivileges = async (
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>,
indices: string[]
) =>
export const checkPrivileges = async (services: AlertServices, indices: string[]) =>
services.callCluster('transport.request', {
path: '/_security/user/_has_privileges',
method: 'POST',
@ -162,7 +154,7 @@ export const getListsClient = ({
lists: ListPluginSetup | undefined;
spaceId: string;
updatedByUser: string | null;
services: AlertServices<AlertInstanceState, AlertInstanceContext, 'default'>;
services: AlertServices;
savedObjectClient: SavedObjectsClientContract;
}): {
listClient: ListClient;

View file

@ -141,8 +141,7 @@ export type GeoContainmentAlertType = AlertType<
GeoContainmentParams,
GeoContainmentState,
GeoContainmentInstanceState,
GeoContainmentInstanceContext,
typeof ActionGroupId
GeoContainmentInstanceContext
>;
export function getAlertType(logger: Logger): GeoContainmentAlertType {

View file

@ -100,8 +100,7 @@ export function getActiveEntriesAndGenerateAlerts(
currLocationMap: Map<string, LatestEntityLocation>,
alertInstanceFactory: AlertServices<
GeoContainmentInstanceState,
GeoContainmentInstanceContext,
typeof ActionGroupId
GeoContainmentInstanceContext
>['alertInstanceFactory'],
shapesIdsNamesMap: Record<string, unknown>,
currIntervalEndTime: Date

View file

@ -12,7 +12,6 @@ import {
GeoContainmentInstanceState,
GeoContainmentInstanceContext,
getAlertType,
ActionGroupId,
} from './alert_type';
interface RegisterParams {
@ -26,7 +25,6 @@ export function register(params: RegisterParams) {
GeoContainmentParams,
GeoContainmentState,
GeoContainmentInstanceState,
GeoContainmentInstanceContext,
typeof ActionGroupId
GeoContainmentInstanceContext
>(getAlertType(logger));
}

View file

@ -209,8 +209,7 @@ export type GeoThresholdAlertType = AlertType<
GeoThresholdParams,
GeoThresholdState,
GeoThresholdInstanceState,
GeoThresholdInstanceContext,
typeof ActionGroupId
GeoThresholdInstanceContext
>;
export function getAlertType(logger: Logger): GeoThresholdAlertType {
const alertTypeName = i18n.translate('xpack.stackAlerts.geoThreshold.alertTypeTitle', {

View file

@ -42,7 +42,7 @@ export const ComparatorFnNames = new Set(ComparatorFns.keys());
export function getAlertType(
logger: Logger,
data: Promise<StackAlertsStartDeps['triggersActionsUi']['data']>
): AlertType<Params, {}, {}, ActionContext, typeof ActionGroupId> {
): AlertType<Params, {}, {}, ActionContext> {
const alertTypeName = i18n.translate('xpack.stackAlerts.indexThreshold.alertTypeTitle', {
defaultMessage: 'Index threshold',
});
@ -148,9 +148,7 @@ export function getAlertType(
producer: STACK_ALERTS_FEATURE_ID,
};
async function executor(
options: AlertExecutorOptions<Params, {}, {}, ActionContext, typeof ActionGroupId>
) {
async function executor(options: AlertExecutorOptions<Params, {}, {}, ActionContext>) {
const { alertId, name, services, params } = options;
const compareFn = ComparatorFns.get(params.thresholdComparator);

View file

@ -39,7 +39,7 @@ import { ActionGroup, AlertActionParam } from '../../../../../alerts/common';
import { useKibana } from '../../../common/lib/kibana';
import { DefaultActionParamsGetter } from '../../lib/get_defaults_for_action_params';
export interface ActionGroupWithMessageVariables extends ActionGroup<string> {
export interface ActionGroupWithMessageVariables extends ActionGroup {
omitOptionalMessageVariables?: boolean;
defaultActionMessage?: string;
}

View file

@ -11,7 +11,6 @@ import { Alert, ActionType, AlertTypeModel, AlertType } from '../../../../types'
import { EuiTitle, EuiBadge, EuiFlexItem, EuiSwitch, EuiButtonEmpty, EuiText } from '@elastic/eui';
import { ViewInApp } from './view_in_app';
import {
ActionGroup,
AlertExecutionStatusErrorReasons,
ALERTS_FEATURE_ID,
} from '../../../../../../alerts/common';
@ -48,7 +47,7 @@ const mockAlertApis = {
const authorizedConsumers = {
[ALERTS_FEATURE_ID]: { read: true, all: true },
};
const recoveryActionGroup: ActionGroup<'recovered'> = { id: 'recovered', name: 'Recovered' };
const recoveryActionGroup = { id: 'recovered', name: 'Recovered' };
describe('alert_details', () => {
// mock Api handlers

View file

@ -231,7 +231,7 @@ const INACTIVE_LABEL = i18n.translate(
function getActionGroupName(alertType: AlertType, actionGroupId?: string): string | undefined {
actionGroupId = actionGroupId || alertType.defaultActionGroupId;
const actionGroup = alertType?.actionGroups?.find(
(group: ActionGroup<string>) => group.id === actionGroupId
(group: ActionGroup) => group.id === actionGroupId
);
return actionGroup?.name;
}

View file

@ -61,7 +61,7 @@ describe('alert_conditions', () => {
const ConditionForm = ({
actionGroup,
}: {
actionGroup?: ActionGroupWithCondition<{ someProp: string }, string>;
actionGroup?: ActionGroupWithCondition<{ someProp: string }>;
}) => {
return (
<EuiDescriptionList>
@ -113,7 +113,7 @@ describe('alert_conditions', () => {
const ConditionForm = ({
actionGroup,
}: {
actionGroup?: ActionGroupWithCondition<{ someProp: string }, string>;
actionGroup?: ActionGroupWithCondition<{ someProp: string }>;
}) => {
return (
<EuiDescriptionList>
@ -165,7 +165,7 @@ describe('alert_conditions', () => {
const ConditionForm = ({
actionGroup,
}: {
actionGroup?: ActionGroupWithCondition<{ someProp: string }, string>;
actionGroup?: ActionGroupWithCondition<{ someProp: string }>;
}) => {
return (
<EuiDescriptionList>
@ -218,10 +218,8 @@ describe('alert_conditions', () => {
actionGroup,
someCallbackProp,
}: {
actionGroup?: ActionGroupWithCondition<{ someProp: string }, string>;
someCallbackProp: (
actionGroup: ActionGroupWithCondition<{ someProp: string }, string>
) => void;
actionGroup?: ActionGroupWithCondition<{ someProp: string }>;
someCallbackProp: (actionGroup: ActionGroupWithCondition<{ someProp: string }>) => void;
}) => {
if (!actionGroup) {
return <div />;

View file

@ -11,10 +11,7 @@ import { ActionGroup, getBuiltinActionGroups } from '../../../../../alerts/commo
const BUILT_IN_ACTION_GROUPS: Set<string> = new Set(getBuiltinActionGroups().map(({ id }) => id));
export type ActionGroupWithCondition<
T,
ActionGroupIds extends string
> = ActionGroup<ActionGroupIds> &
export type ActionGroupWithCondition<T> = ActionGroup &
(
| // allow isRequired=false with or without conditions
{
@ -28,26 +25,22 @@ export type ActionGroupWithCondition<
}
);
export interface AlertConditionsProps<ConditionProps, ActionGroupIds extends string> {
export interface AlertConditionsProps<ConditionProps> {
headline?: string;
actionGroups: Array<ActionGroupWithCondition<ConditionProps, ActionGroupIds>>;
onInitializeConditionsFor?: (
actionGroup: ActionGroupWithCondition<ConditionProps, ActionGroupIds>
) => void;
onResetConditionsFor?: (
actionGroup: ActionGroupWithCondition<ConditionProps, ActionGroupIds>
) => void;
actionGroups: Array<ActionGroupWithCondition<ConditionProps>>;
onInitializeConditionsFor?: (actionGroup: ActionGroupWithCondition<ConditionProps>) => void;
onResetConditionsFor?: (actionGroup: ActionGroupWithCondition<ConditionProps>) => void;
includeBuiltInActionGroups?: boolean;
}
export const AlertConditions = <ConditionProps extends any, ActionGroupIds extends string>({
export const AlertConditions = <ConditionProps extends any>({
headline,
actionGroups,
onInitializeConditionsFor,
onResetConditionsFor,
includeBuiltInActionGroups = false,
children,
}: PropsWithChildren<AlertConditionsProps<ConditionProps, ActionGroupIds>>) => {
}: PropsWithChildren<AlertConditionsProps<ConditionProps>>) => {
const [withConditions, withoutConditions] = partition(
includeBuiltInActionGroups
? actionGroups

View file

@ -9,8 +9,8 @@ import { EuiFormRow, EuiButtonIcon, EuiTitle } from '@elastic/eui';
import { AlertConditionsProps, ActionGroupWithCondition } from './alert_conditions';
export type AlertConditionsGroupProps<ConditionProps> = {
actionGroup?: ActionGroupWithCondition<ConditionProps, string>;
} & Pick<AlertConditionsProps<ConditionProps, string>, 'onResetConditionsFor'>;
actionGroup?: ActionGroupWithCondition<ConditionProps>;
} & Pick<AlertConditionsProps<ConditionProps>, 'onResetConditionsFor'>;
export const AlertConditionsGroup = <ConditionProps extends unknown>({
actionGroup,

View file

@ -144,11 +144,9 @@ export const OPTIONAL_ACTION_VARIABLES = ['context'] as const;
export type ActionVariables = AsActionVariables<typeof REQUIRED_ACTION_VARIABLES[number]> &
Partial<AsActionVariables<typeof OPTIONAL_ACTION_VARIABLES[number]>>;
export interface AlertType<
ActionGroupIds extends string = string,
RecoveryActionGroupId extends string = string
> extends Pick<
CommonAlertType<ActionGroupIds, RecoveryActionGroupId>,
export interface AlertType
extends Pick<
CommonAlertType,
| 'id'
| 'name'
| 'actionGroups'
@ -175,8 +173,7 @@ export interface AlertTableItem extends Alert {
export interface AlertTypeParamsExpressionProps<
Params extends AlertTypeParams = AlertTypeParams,
MetaData = Record<string, any>,
ActionGroupIds extends string = string
MetaData = Record<string, any>
> {
alertParams: Params;
alertInterval: string;
@ -188,7 +185,7 @@ export interface AlertTypeParamsExpressionProps<
) => void;
errors: IErrorObject;
defaultActionGroupId: string;
actionGroups: Array<ActionGroup<ActionGroupIds>>;
actionGroups: ActionGroup[];
metadata?: MetaData;
charts: ChartsPluginSetup;
data: DataPublicPluginStart;

View file

@ -4,13 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ActionGroup } from '../../../alerts/common';
interface ActionGroupDefinition {
id: string;
name: string;
}
export const ACTION_GROUP_DEFINITIONS: {
MONITOR_STATUS: ActionGroup<'xpack.uptime.alerts.actionGroups.monitorStatus'>;
TLS: ActionGroup<'xpack.uptime.alerts.actionGroups.tls'>;
DURATION_ANOMALY: ActionGroup<'xpack.uptime.alerts.actionGroups.durationAnomaly'>;
} = {
type ActionGroupDefinitions = Record<string, ActionGroupDefinition>;
export const ACTION_GROUP_DEFINITIONS: ActionGroupDefinitions = {
MONITOR_STATUS: {
id: 'xpack.uptime.alerts.actionGroups.monitorStatus',
name: 'Uptime Down Monitor',

View file

@ -874,13 +874,7 @@ describe('status check alert', () => {
});
describe('alert factory', () => {
let alert: AlertType<
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
'xpack.uptime.alerts.actionGroups.monitorStatus'
>;
let alert: AlertType<AlertTypeParams, AlertTypeState, AlertInstanceState, AlertInstanceContext>;
beforeEach(() => {
const { server, libs, plugins } = bootstrapDependencies();

View file

@ -7,7 +7,6 @@
import { KibanaRequest, SavedObjectsClientContract } from 'kibana/server';
import moment from 'moment';
import { schema } from '@kbn/config-schema';
import { ActionGroupIdsOf } from '../../../../alerts/common';
import { updateState } from './common';
import { ACTION_GROUP_DEFINITIONS } from '../../../common/constants/alerts';
import { commonStateTranslations, durationAnomalyTranslations } from './translations';
@ -21,7 +20,6 @@ import { getLatestMonitor } from '../requests/get_latest_monitor';
import { uptimeAlertWrapper } from './uptime_alert_wrapper';
const { DURATION_ANOMALY } = ACTION_GROUP_DEFINITIONS;
export type ActionGroupIds = ActionGroupIdsOf<typeof DURATION_ANOMALY>;
export const getAnomalySummary = (anomaly: AnomaliesTableRecord, monitorInfo: Ping) => {
return {
@ -63,12 +61,8 @@ const getAnomalies = async (
);
};
export const durationAnomalyAlertFactory: UptimeAlertTypeFactory<ActionGroupIds> = (
_server,
_libs,
plugins
) =>
uptimeAlertWrapper<ActionGroupIds>({
export const durationAnomalyAlertFactory: UptimeAlertTypeFactory = (_server, _libs, plugins) =>
uptimeAlertWrapper({
id: 'xpack.uptime.alerts.durationAnomaly',
name: durationAnomalyTranslations.alertFactoryName,
validate: {

View file

@ -5,15 +5,12 @@
*/
import { UptimeAlertTypeFactory } from './types';
import { statusCheckAlertFactory, ActionGroupIds as statusCheckActionGroup } from './status_check';
import { tlsAlertFactory, ActionGroupIds as tlsActionGroup } from './tls';
import {
durationAnomalyAlertFactory,
ActionGroupIds as durationAnomalyActionGroup,
} from './duration_anomaly';
import { statusCheckAlertFactory } from './status_check';
import { tlsAlertFactory } from './tls';
import { durationAnomalyAlertFactory } from './duration_anomaly';
export const uptimeAlertTypeFactories: [
UptimeAlertTypeFactory<statusCheckActionGroup>,
UptimeAlertTypeFactory<tlsActionGroup>,
UptimeAlertTypeFactory<durationAnomalyActionGroup>
] = [statusCheckAlertFactory, tlsAlertFactory, durationAnomalyAlertFactory];
export const uptimeAlertTypeFactories: UptimeAlertTypeFactory[] = [
statusCheckAlertFactory,
tlsAlertFactory,
durationAnomalyAlertFactory,
];

View file

@ -7,7 +7,6 @@
import { schema } from '@kbn/config-schema';
import { i18n } from '@kbn/i18n';
import Mustache from 'mustache';
import { ActionGroupIdsOf } from '../../../../alerts/common';
import { UptimeAlertTypeFactory } from './types';
import { esKuery } from '../../../../../../src/plugins/data/server';
import { JsonObject } from '../../../../../../src/plugins/kibana_utils/common';
@ -29,7 +28,6 @@ import { getUptimeIndexPattern, IndexPatternTitleAndFields } from '../requests/g
import { UMServerLibs, UptimeESClient } from '../lib';
const { MONITOR_STATUS } = ACTION_GROUP_DEFINITIONS;
export type ActionGroupIds = ActionGroupIdsOf<typeof MONITOR_STATUS>;
const getMonIdByLoc = (monitorId: string, location: string) => {
return monitorId + '-' + location;
@ -180,8 +178,8 @@ const getInstanceId = (monitorInfo: Ping, monIdByLoc: string) => {
return `${urlText}_${monIdByLoc}`;
};
export const statusCheckAlertFactory: UptimeAlertTypeFactory<ActionGroupIds> = (_server, libs) =>
uptimeAlertWrapper<ActionGroupIds>({
export const statusCheckAlertFactory: UptimeAlertTypeFactory = (_server, libs) =>
uptimeAlertWrapper({
id: 'xpack.uptime.alerts.monitorStatus',
name: i18n.translate('xpack.uptime.alerts.monitorStatus', {
defaultMessage: 'Uptime monitor status',

View file

@ -14,10 +14,8 @@ import { Cert, CertResult } from '../../../common/runtime_types';
import { commonStateTranslations, tlsTranslations } from './translations';
import { DEFAULT_FROM, DEFAULT_TO } from '../../rest_api/certs/certs';
import { uptimeAlertWrapper } from './uptime_alert_wrapper';
import { ActionGroupIdsOf } from '../../../../alerts/common';
const { TLS } = ACTION_GROUP_DEFINITIONS;
export type ActionGroupIds = ActionGroupIdsOf<typeof TLS>;
const DEFAULT_SIZE = 20;
@ -84,8 +82,8 @@ export const getCertSummary = (
};
};
export const tlsAlertFactory: UptimeAlertTypeFactory<ActionGroupIds> = (_server, libs) =>
uptimeAlertWrapper<ActionGroupIds>({
export const tlsAlertFactory: UptimeAlertTypeFactory = (_server, libs) =>
uptimeAlertWrapper({
id: 'xpack.uptime.alerts.tls',
name: tlsTranslations.alertFactoryName,
validate: {

View file

@ -10,7 +10,7 @@ import { AlertType, AlertInstanceState, AlertInstanceContext } from '../../../..
export type UptimeAlertTypeParam = Record<string, any>;
export type UptimeAlertTypeState = Record<string, any>;
export type UptimeAlertTypeFactory<ActionGroupIds extends string> = (
export type UptimeAlertTypeFactory = (
server: UptimeCoreSetup,
libs: UMServerLibs,
plugins: UptimeCorePlugins
@ -18,6 +18,5 @@ export type UptimeAlertTypeFactory<ActionGroupIds extends string> = (
UptimeAlertTypeParam,
UptimeAlertTypeState,
AlertInstanceState,
AlertInstanceContext,
ActionGroupIds
AlertInstanceContext
>;

View file

@ -15,8 +15,8 @@ import { DynamicSettings } from '../../../common/runtime_types';
import { createUptimeESClient, UptimeESClient } from '../lib';
import { UptimeAlertTypeFactory, UptimeAlertTypeParam, UptimeAlertTypeState } from './types';
export interface UptimeAlertType<ActionGroupIds extends string>
extends Omit<ReturnType<UptimeAlertTypeFactory<ActionGroupIds>>, 'executor' | 'producer'> {
export interface UptimeAlertType
extends Omit<ReturnType<UptimeAlertTypeFactory>, 'executor' | 'producer'> {
executor: ({
options,
uptimeEsClient,
@ -26,8 +26,7 @@ export interface UptimeAlertType<ActionGroupIds extends string>
UptimeAlertTypeParam,
UptimeAlertTypeState,
AlertInstanceState,
AlertInstanceContext,
ActionGroupIds
AlertInstanceContext
>;
uptimeEsClient: UptimeESClient;
dynamicSettings: DynamicSettings;
@ -35,9 +34,7 @@ export interface UptimeAlertType<ActionGroupIds extends string>
}) => Promise<UptimeAlertTypeState | void>;
}
export const uptimeAlertWrapper = <ActionGroupIds extends string>(
uptimeAlert: UptimeAlertType<ActionGroupIds>
) => ({
export const uptimeAlertWrapper = (uptimeAlert: UptimeAlertType) => ({
...uptimeAlert,
producer: 'uptime',
executor: async (
@ -45,8 +42,7 @@ export const uptimeAlertWrapper = <ActionGroupIds extends string>(
UptimeAlertTypeParam,
UptimeAlertTypeState,
AlertInstanceState,
AlertInstanceContext,
ActionGroupIds
AlertInstanceContext
>
) => {
const {

View file

@ -61,13 +61,7 @@ function getAlwaysFiringAlertType() {
interface InstanceContext extends AlertInstanceContext {
instanceContextValue: boolean;
}
const result: AlertType<
ParamsType & AlertTypeParams,
State,
InstanceState,
InstanceContext,
'default' | 'other'
> = {
const result: AlertType<ParamsType & AlertTypeParams, State, InstanceState, InstanceContext> = {
id: 'test.always-firing',
name: 'Test: Always Firing',
actionGroups: [
@ -155,7 +149,7 @@ function getCumulativeFiringAlertType() {
interface InstanceState extends AlertInstanceState {
instanceStateValue: boolean;
}
const result: AlertType<{}, State, InstanceState, {}, 'default' | 'other'> = {
const result: AlertType<{}, State, InstanceState, {}> = {
id: 'test.cumulative-firing',
name: 'Test: Cumulative Firing',
actionGroups: [
@ -195,7 +189,7 @@ function getNeverFiringAlertType() {
interface State extends AlertTypeState {
globalStateValue: boolean;
}
const result: AlertType<ParamsType, State, {}, {}, 'default'> = {
const result: AlertType<ParamsType, State, {}, {}> = {
id: 'test.never-firing',
name: 'Test: Never firing',
actionGroups: [
@ -235,7 +229,7 @@ function getFailingAlertType() {
reference: schema.string(),
});
type ParamsType = TypeOf<typeof paramsSchema>;
const result: AlertType<ParamsType, {}, {}, {}, 'default'> = {
const result: AlertType<ParamsType, {}, {}, {}> = {
id: 'test.failing',
name: 'Test: Failing',
validate: {
@ -277,7 +271,7 @@ function getAuthorizationAlertType(core: CoreSetup<FixtureStartDeps>) {
reference: schema.string(),
});
type ParamsType = TypeOf<typeof paramsSchema>;
const result: AlertType<ParamsType, {}, {}, {}, 'default'> = {
const result: AlertType<ParamsType, {}, {}, {}> = {
id: 'test.authorization',
name: 'Test: Authorization',
actionGroups: [
@ -364,7 +358,7 @@ function getValidationAlertType() {
param1: schema.string(),
});
type ParamsType = TypeOf<typeof paramsSchema>;
const result: AlertType<ParamsType, {}, {}, {}, 'default'> = {
const result: AlertType<ParamsType, {}, {}, {}> = {
id: 'test.validation',
name: 'Test: Validation',
actionGroups: [
@ -396,7 +390,7 @@ function getPatternFiringAlertType() {
interface State extends AlertTypeState {
patternIndex?: number;
}
const result: AlertType<ParamsType, State, {}, {}, 'default'> = {
const result: AlertType<ParamsType, State, {}, {}> = {
id: 'test.patternFiring',
name: 'Test: Firing on a Pattern',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -460,7 +454,7 @@ export function defineAlertTypes(
core: CoreSetup<FixtureStartDeps>,
{ alerts }: Pick<FixtureSetupDeps, 'alerts'>
) {
const noopAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
const noopAlertType: AlertType = {
id: 'test.noop',
name: 'Test: Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -469,7 +463,7 @@ export function defineAlertTypes(
minimumLicenseRequired: 'basic',
async executor() {},
};
const goldNoopAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
const goldNoopAlertType: AlertType = {
id: 'test.gold.noop',
name: 'Test: Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -478,7 +472,7 @@ export function defineAlertTypes(
minimumLicenseRequired: 'gold',
async executor() {},
};
const onlyContextVariablesAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
const onlyContextVariablesAlertType: AlertType = {
id: 'test.onlyContextVariables',
name: 'Test: Only Context Variables',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -490,7 +484,7 @@ export function defineAlertTypes(
},
async executor() {},
};
const onlyStateVariablesAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
const onlyStateVariablesAlertType: AlertType = {
id: 'test.onlyStateVariables',
name: 'Test: Only State Variables',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -502,7 +496,7 @@ export function defineAlertTypes(
minimumLicenseRequired: 'basic',
async executor() {},
};
const throwAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
const throwAlertType: AlertType = {
id: 'test.throw',
name: 'Test: Throw',
actionGroups: [
@ -518,7 +512,7 @@ export function defineAlertTypes(
throw new Error('this alert is intended to fail');
},
};
const longRunningAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
const longRunningAlertType: AlertType = {
id: 'test.longRunning',
name: 'Test: Long Running',
actionGroups: [

View file

@ -6,13 +6,13 @@
import { CoreSetup } from 'src/core/server';
import { FixtureStartDeps, FixtureSetupDeps } from './plugin';
import { AlertType } from '../../../../../../../plugins/alerts/server';
import { AlertType, AlertExecutorOptions } from '../../../../../../../plugins/alerts/server';
export function defineAlertTypes(
core: CoreSetup<FixtureStartDeps>,
{ alerts }: Pick<FixtureSetupDeps, 'alerts'>
) {
const noopRestrictedAlertType: AlertType<{}, {}, {}, {}, 'default', 'restrictedRecovered'> = {
const noopRestrictedAlertType: AlertType = {
id: 'test.restricted-noop',
name: 'Test: Restricted Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -20,16 +20,16 @@ export function defineAlertTypes(
defaultActionGroupId: 'default',
minimumLicenseRequired: 'basic',
recoveryActionGroup: { id: 'restrictedRecovered', name: 'Restricted Recovery' },
async executor() {},
async executor({ services, params, state }: AlertExecutorOptions) {},
};
const noopUnrestrictedAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
const noopUnrestrictedAlertType: AlertType = {
id: 'test.unrestricted-noop',
name: 'Test: Unrestricted Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
producer: 'alertsRestrictedFixture',
defaultActionGroupId: 'default',
minimumLicenseRequired: 'basic',
async executor() {},
async executor({ services, params, state }: AlertExecutorOptions) {},
};
alerts.registerType(noopRestrictedAlertType);
alerts.registerType(noopUnrestrictedAlertType);

View file

@ -17,7 +17,7 @@ export interface AlertingExampleDeps {
features: FeaturesPluginSetup;
}
export const noopAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
export const noopAlertType: AlertType = {
id: 'test.noop',
name: 'Test: Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -33,9 +33,7 @@ export const alwaysFiringAlertType: AlertType<
globalStateValue: boolean;
groupInSeriesIndex: number;
},
{ instanceStateValue: boolean; globalStateValue: boolean; groupInSeriesIndex: number },
never,
'default' | 'other'
{ instanceStateValue: boolean; globalStateValue: boolean; groupInSeriesIndex: number }
> = {
id: 'test.always-firing',
name: 'Always Firing',
@ -63,7 +61,7 @@ export const alwaysFiringAlertType: AlertType<
},
};
export const failingAlertType: AlertType<never, never, never, never, 'default' | 'other'> = {
export const failingAlertType: AlertType = {
id: 'test.failing',
name: 'Test: Failing',
actionGroups: [