Skip to content

Commit

Permalink
[Alerting] Allow rule types to extract/inject saved object references…
Browse files Browse the repository at this point in the history
… on rule CRU (elastic#101896)

* Adding function hooks into rule type definition and call extract fn on rule create

* Adding hooks for extracting and injecting saved object references. Adding extractReferences to create and update workflow

* Adding type template for extracted params

* Adding type template for extracted params

* Adding type template for extracted params

* Adding type template for extracted params

* Calling injectReferences function if defined. Finishing unit tests for create and update

* Adding tests for get

* Adding tests for find

* Cleanup

* Fixing types check

* Fixing functional tests

* Fixing functional tests

* Fixing tests

* Updating README

* Throwing boom error instead of normal error

* Adding framework level prefix to extracted saved object reference names

* Fixing types

* Fixing types

* PR fixes

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
ymao1 and kibanamachine committed Jul 23, 2021
1 parent 88eb5cd commit 74a9427
Show file tree
Hide file tree
Showing 36 changed files with 1,339 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function getTShirtSizeByIdAndThreshold(

export const alertType: AlertType<
AlwaysFiringParams,
never,
{ count?: number },
{ triggerdOnCycle: number },
never,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function getCraftFilter(craft: string) {

export const alertType: AlertType<
{ outerSpaceCapacity: number; craft: string; op: string },
never,
{ peopleInSpace: number },
{ craft: string },
never,
Expand Down
47 changes: 47 additions & 0 deletions x-pack/plugins/alerting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ The following table describes the properties of the `options` object.
|executor|This is where the code for the rule type lives. This is a function to be called when executing a rule on an interval basis. For full details, see the executor section below.|Function|
|producer|The id of the application producing this rule type.|string|
|minimumLicenseRequired|The value of a minimum license. Most of the rules are licensed as "basic".|string|
|useSavedObjectReferences.extractReferences|(Optional) When developing a rule type, you can choose to implement hooks for extracting saved object references from rule parameters. This hook will be invoked when a rule is created or updated. Implementing this hook is optional, but if an extract hook is implemented, an inject hook must also be implemented.|Function
|useSavedObjectReferences.injectReferences|(Optional) When developing a rule type, you can choose to implement hooks for injecting saved object references into rule parameters. This hook will be invoked when a rule is retrieved (get or find). Implementing this hook is optional, but if an inject hook is implemented, an extract hook must also be implemented.|Function
|isExportable|Whether the rule type is exportable from the Saved Objects Management UI.|boolean|

### Executor
Expand Down Expand Up @@ -173,6 +175,19 @@ For example, if the `context` has one variable `foo` which is an object that has
}
```

### useSavedObjectReferences Hooks

This is an optional pair of functions that can be implemented by a rule type. Both `extractReferences` and `injectReferences` functions must be implemented if either is impemented.

**useSavedObjectReferences.extractReferences**

This function should take the rule type params as input and extract out any saved object IDs stored within the params. For each saved object ID, a new saved object reference should be created and a saved object reference should replace the saved object ID in the rule params. This function should return the modified rule type params (with saved object reference name, not IDs) and an array of saved object references.


**useSavedObjectReferences.injectReferences**


This function should take the rule type params (with saved object references) and the saved object references array as input and inject the saved object ID in place of any saved object references in the rule type params. Note that any error thrown within this function will be propagated.
## Licensing

Currently most rule types are free features. But some rule types are subscription features, such as the tracking containment rule.
Expand Down Expand Up @@ -210,6 +225,13 @@ import {
interface MyRuleTypeParams extends AlertTypeParams {
server: string;
threshold: number;
testSavedObjectId: string;
}

interface MyRuleTypeExtractedParams extends AlertTypeParams {
server: string;
threshold: number;
testSavedObjectRef: string;
}

interface MyRuleTypeState extends AlertTypeState {
Expand All @@ -229,6 +251,7 @@ type MyRuleTypeActionGroups = 'default' | 'warning';

const myRuleType: AlertType<
MyRuleTypeParams,
MyRuleTypeExtractedParams,
MyRuleTypeState,
MyRuleTypeAlertState,
MyRuleTypeAlertContext,
Expand Down Expand Up @@ -274,6 +297,7 @@ const myRuleType: AlertType<
rule,
}: AlertExecutorOptions<
MyRuleTypeParams,
MyRuleTypeExtractedParams,
MyRuleTypeState,
MyRuleTypeAlertState,
MyRuleTypeAlertContext,
Expand Down Expand Up @@ -320,6 +344,29 @@ const myRuleType: AlertType<
};
},
producer: 'alerting',
useSavedObjectReferences: {
extractReferences: (params: Params): RuleParamsAndRefs<ExtractedParams> => {
const { testSavedObjectId, ...otherParams } = params;

const testSavedObjectRef = 'testRef_0';
const references = [
{
name: `testRef_0`,
id: testSavedObjectId,
type: 'index-pattern',
},
];
return { params: { ...otherParams, testSavedObjectRef }, references };
},
injectReferences: (params: SavedObjectAttributes, references: SavedObjectReference[]) => {
const { testSavedObjectRef, ...otherParams } = params;
const reference = references.find((ref) => ref.name === testSavedObjectRef);
if (!reference) {
throw new Error(`Test reference "${testSavedObjectRef}"`);
}
return { ...otherParams, testSavedObjectId: reference.id } as Params;
},
}
};

server.newPlatform.setup.plugins.alerting.registerType(myRuleType);
Expand Down
17 changes: 9 additions & 8 deletions x-pack/plugins/alerting/server/alert_type_registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('has()', () => {

describe('register()', () => {
test('throws if AlertType Id contains invalid characters', () => {
const alertType: AlertType<never, never, never, never, 'default'> = {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
id: 'test',
name: 'Test',
actionGroups: [
Expand Down Expand Up @@ -90,7 +90,7 @@ describe('register()', () => {
});

test('throws if AlertType Id isnt a string', () => {
const alertType: AlertType<never, never, never, never, 'default'> = {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
id: (123 as unknown) as string,
name: 'Test',
actionGroups: [
Expand All @@ -113,7 +113,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<never, never, never, never, never, 'default' | 'NotReserved'> = {
id: 'test',
name: 'Test',
actionGroups: [
Expand Down Expand Up @@ -146,7 +146,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<never, never, never, never, never, 'default', 'backToAwesome'> = {
id: 'test',
name: 'Test',
actionGroups: [
Expand Down Expand Up @@ -187,6 +187,7 @@ describe('register()', () => {
never,
never,
never,
never,
'default' | 'backToAwesome',
'backToAwesome'
> = {
Expand Down Expand Up @@ -222,7 +223,7 @@ describe('register()', () => {
});

test('registers the executor with the task manager', () => {
const alertType: AlertType<never, never, never, never, 'default'> = {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
id: 'test',
name: 'Test',
actionGroups: [
Expand Down Expand Up @@ -253,7 +254,7 @@ describe('register()', () => {
});

test('shallow clones the given alert type', () => {
const alertType: AlertType<never, never, never, never, 'default'> = {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
id: 'test',
name: 'Test',
actionGroups: [
Expand Down Expand Up @@ -506,8 +507,8 @@ 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> = {
): AlertType<never, never, never, never, never, ActionGroupIds> {
const baseAlert: AlertType<never, never, never, never, never, ActionGroupIds> = {
id,
name: `${id}-name`,
actionGroups: [],
Expand Down
23 changes: 22 additions & 1 deletion x-pack/plugins/alerting/server/alert_type_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const alertIdSchema = schema.string({

export type NormalizedAlertType<
Params extends AlertTypeParams,
ExtractedParams extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
Expand All @@ -82,13 +83,22 @@ export type NormalizedAlertType<
> = {
actionGroups: Array<ActionGroup<ActionGroupIds | RecoveryActionGroupId>>;
} & Omit<
AlertType<Params, State, InstanceState, InstanceContext, ActionGroupIds, RecoveryActionGroupId>,
AlertType<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>,
'recoveryActionGroup' | 'actionGroups'
> &
Pick<
Required<
AlertType<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
Expand All @@ -100,6 +110,7 @@ export type NormalizedAlertType<
>;

export type UntypedNormalizedAlertType = NormalizedAlertType<
AlertTypeParams,
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
Expand Down Expand Up @@ -132,6 +143,7 @@ export class AlertTypeRegistry {

public register<
Params extends AlertTypeParams,
ExtractedParams extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
Expand All @@ -140,6 +152,7 @@ export class AlertTypeRegistry {
>(
alertType: AlertType<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
Expand All @@ -161,6 +174,7 @@ export class AlertTypeRegistry {

const normalizedAlertType = augmentActionGroupsWithReserved<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
Expand All @@ -179,6 +193,7 @@ export class AlertTypeRegistry {
createTaskRunner: (context: RunContext) =>
this.taskRunnerFactory.create<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
Expand All @@ -198,6 +213,7 @@ export class AlertTypeRegistry {

public get<
Params extends AlertTypeParams = AlertTypeParams,
ExtractedParams extends AlertTypeParams = AlertTypeParams,
State extends AlertTypeState = AlertTypeState,
InstanceState extends AlertInstanceState = AlertInstanceState,
InstanceContext extends AlertInstanceContext = AlertInstanceContext,
Expand All @@ -207,6 +223,7 @@ export class AlertTypeRegistry {
id: string
): NormalizedAlertType<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
Expand All @@ -230,6 +247,7 @@ export class AlertTypeRegistry {
*/
return (this.alertTypes.get(id)! as unknown) as NormalizedAlertType<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
Expand Down Expand Up @@ -284,6 +302,7 @@ function normalizedActionVariables(actionVariables: AlertType['actionVariables']

function augmentActionGroupsWithReserved<
Params extends AlertTypeParams,
ExtractedParams extends AlertTypeParams,
State extends AlertTypeState,
InstanceState extends AlertInstanceState,
InstanceContext extends AlertInstanceContext,
Expand All @@ -292,6 +311,7 @@ function augmentActionGroupsWithReserved<
>(
alertType: AlertType<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
Expand All @@ -300,6 +320,7 @@ function augmentActionGroupsWithReserved<
>
): NormalizedAlertType<
Params,
ExtractedParams,
State,
InstanceState,
InstanceContext,
Expand Down

0 comments on commit 74a9427

Please sign in to comment.