Skip to content

Commit

Permalink
[ResponseOps] add pre-create, pre-update, and post-delete hooks for c…
Browse files Browse the repository at this point in the history
…onnectors

Extracted from #189027,
commit c97afeb

Allows connector types to add functions to be called when connectors are
created, updated, and deleted.
  • Loading branch information
pmuellr committed Oct 7, 2024
1 parent 77c89d2 commit fd3ce86
Show file tree
Hide file tree
Showing 10 changed files with 619 additions and 31 deletions.
71 changes: 69 additions & 2 deletions x-pack/plugins/actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,16 @@ The following table describes the properties of the `options` object.
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| id | Unique identifier for the action type. For convention, ids starting with `.` are reserved for built in action types. We recommend using a convention like `<plugin_id>.mySpecialAction` for your action types. | string |
| name | A user-friendly name for the action type. These will be displayed in dropdowns when chosing action types. | string |
| maxAttempts | The maximum number of times this action will attempt to run when scheduled. | number |
| maxAttempts | The maximum number of times this action will attempt to run when scheduled. | number |
| minimumLicenseRequired | The license required to use the action type. | string |
| supportedFeatureIds | List of IDs of the features that this action type is available in. Allowed values are `alerting`, `siem`, `uptime`, `cases`. See `x-pack/plugins/actions/common/connector_feature_config.ts` for the most up to date list. | string[] |
| validate.params | When developing an action type, it needs to accept parameters to know what to do with the action. (Example `to`, `from`, `subject`, `body` of an email). See the current built-in email action type for an example of the state-of-the-art validation. <p>Technically, the value of this property should have a property named `validate()` which is a function that takes a params object to validate and returns a sanitized version of that object to pass to the execution function. Validation errors should be thrown from the `validate()` function and will be available as an error message | schema / validation function |
| validate.config | Similar to params, a config may be required when creating an action (for example `host` and `port` for an email server). | schema / validation function |
| validate.secrets | Similar to params, a secrets object may be required when creating an action (for example `user` and `password` for an email server). | schema / validation function |
| executor | This is where the code of an action type lives. This is a function gets called for generating an action from either alerting or manually by using the exposed function (see firing actions). For full details, see executor section below. | Function |
| executor | This is where the code of an action type lives. This is a function gets called for generating an action from either alerting or manually by using the exposed function (see firing actions). For full details, see executor section below. | Function |
| preSaveHook | This optional function is called before the connector saved object is saved. For full details, see hooks section below. | Function |
| postSaveHook | This optional function is called after the connector saved object is saved. For full details, see hooks section below. | Function |
| postDeleteHook | This optional function is called after the connector saved object is deleted. For full details, see hooks section below. | Function |
| renderParameterTemplates | Optionally define a function to provide custom rendering for this action type. | Function |

**Important** - The config object is persisted in ElasticSearch and updated via the ElasticSearch update document API. This API allows "partial updates" - and this can cause issues with the encryption used on specified properties. So, a `validate()` function should return values for all configuration properties, so that partial updates do not occur. Setting property values to `null` rather than `undefined`, or not including a property in the config object, is all you need to do to ensure partial updates won't occur.
Expand All @@ -116,6 +119,70 @@ This is the primary function for an action type. Whenever the action needs to ru
| services.savedObjectsClient | This is an instance of the saved objects client. This provides the ability to do CRUD on any saved objects within the same space the alert lives in.<br><br>The scope of the saved objects client is tied to the user in context calling the execute API or the API key provided to the execute plugin function (only when security isenabled). |
| services.log(tags, [data], [timestamp]) | Use this to create server logs. (This is the same function as server.log) |

### Hooks

Hooks allow a connector implementation to be called during connector creation, update, and delete. When not using hooks, the connector implementation is not involved in creation, update and delete, except for the schema validation that happens for creation and update. Hooks can be used to force a create or update to fail, or run arbitrary code
before and after update and create, and after delete. We don't have a need for a hook before delete at the moment, so that hook is currently not available.

Hooks are passed the following parameters:

```ts
interface PreSaveConnectorHookParams<Config, Secrets> {
connectorId: string;
config: Config;
secrets: Secrets;
logger: Logger;
request: KibanaRequest;
services: HookServices;
isUpdate: boolean;
}

interface PostSaveConnectorHookParams<Config, Secrets> {
connectorId: string;
config: Config;
secrets: Secrets;
logger: Logger;
request: KibanaRequest;
services: HookServices;
isUpdate: boolean;
wasSuccessful: boolean;
}

interface PostDeleteConnectorHookParams<Config, Secrets> {
connectorId: string;
config: Config;
secrets: Secrets;
logger: Logger;
request: KibanaRequest;
services: HookServices;
}
```

| parameter | description
| --------- | -----------
| `connectorId` | The id of the connector.
| `config` | The connector's `config` object.
| `secrets` | The connector's `secrets` object.
| `logger` | A standard Kibana logger.
| `request` | The request causing this operation
| `services` | Common service objects, see below.
| `isUpdate` | For the `PreSave` and `PostSave` hooks, `isUpdate` is false for create operations, and true for update operations.
| `wasSuccessful` | For the `PostSave` hook, this indicates if the connector was persisted as a Saved Object successfully.

The `services` object contains the following properties:

| property | description
| --------- | -----------
| `scopedClusterClient` | A standard `scopeClusterClient` object.

The hooks are called just before, and just after, the Saved Object operation for the client methods is invoked.

The `PostDelete` hook does not have a `wasSuccessful` property, as the hook is not called if the delete operation fails. The saved object will still exist. Only a successful call to delete the connector will cause the hook to run.

The `PreSave` hook can be used to cancel a create or update, by throwing an exception. The `PostSave` and `PostDelete` invocations will have thrown exceptions caught and logged to the Kibana log, and will not cancel the operation.

When throwing an error in the `PreSave` hook, the Error's message will be used as the error failing the operation, so should include a human-readable description of what it was doing, along with any message from an underlying API that failed, if available.

### Example

The built-in email action type provides a good example of creating an action type with non-trivial configuration and params:
Expand Down
Loading

0 comments on commit fd3ce86

Please sign in to comment.