mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Alerting] adds Connectors APIs and deprecates old Actions APIs as per the new Alerting terminology (#92451)
* moved legacy actions api to legacy folder * introduced connector create api * added new delete route * added new execute and get_all * introduced all connector APIs * renamed action to connector in Apis * comment on camel case type * fixed va * updated docs * legacy title * corrected APIs * legacy links * added linik to deprecatred APIs * added linik to deprecatred APIs from index * moved legacy apis down one level * Apply suggestions from code review Co-authored-by: ymao1 <ying.mao@elastic.co> * renamed route file for connectorTypesRoute * define legacy route * Update docs/api/actions-and-connectors/legacy/index.asciidoc Co-authored-by: Mike Côté <mikecote@users.noreply.github.com> * api docs Co-authored-by: ymao1 <ying.mao@elastic.co> Co-authored-by: Mike Côté <mikecote@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
46247c6c55
commit
7cfd15c038
80 changed files with 3373 additions and 864 deletions
|
@ -647,7 +647,9 @@
|
|||
"section": "def-server.ActionResult",
|
||||
"text": "ActionResult"
|
||||
},
|
||||
"<Record<string, unknown>>>; delete: ({ id }: { id: string; }) => Promise<{}>; create: ({ action: { actionTypeId, name, config, secrets }, }: CreateOptions) => Promise<",
|
||||
"<Record<string, unknown>>>; delete: ({ id }: { id: string; }) => Promise<{}>; create: ({ action: { actionTypeId, name, config, secrets }, }: ",
|
||||
"CreateOptions",
|
||||
") => Promise<",
|
||||
{
|
||||
"pluginId": "actions",
|
||||
"scope": "server",
|
||||
|
@ -655,23 +657,15 @@
|
|||
"section": "def-server.ActionResult",
|
||||
"text": "ActionResult"
|
||||
},
|
||||
"<Record<string, unknown>>>; update: ({ id, action }: UpdateOptions) => Promise<",
|
||||
"<Record<string, unknown>>>; update: ({ id, action }: ",
|
||||
"UpdateOptions",
|
||||
") => Promise<",
|
||||
{
|
||||
"pluginId": "actions",
|
||||
"scope": "server",
|
||||
"docId": "kibActionsPluginApi",
|
||||
"section": "def-server.ActionResult",
|
||||
"text": "ActionResult"
|
||||
},
|
||||
"<Record<string, unknown>>>; execute: ({ actionId, params, source, }: Pick<",
|
||||
"ExecuteOptions",
|
||||
"<unknown>, \"source\" | \"params\" | \"actionId\">) => Promise<",
|
||||
{
|
||||
"pluginId": "actions",
|
||||
"scope": "common",
|
||||
"docId": "kibActionsPluginApi",
|
||||
"section": "def-common.ActionTypeExecutorResult",
|
||||
"text": "ActionTypeExecutorResult"
|
||||
}
|
||||
],
|
||||
"initialIsOpen": false
|
||||
|
@ -1071,8 +1065,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 94,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L94"
|
||||
"lineNumber": 86,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L86"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -1080,15 +1074,15 @@
|
|||
"returnComment": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 88,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L88"
|
||||
"lineNumber": 80,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L80"
|
||||
}
|
||||
}
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 87,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L87"
|
||||
"lineNumber": 79,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L79"
|
||||
},
|
||||
"lifecycle": "setup",
|
||||
"initialIsOpen": true
|
||||
|
@ -1119,8 +1113,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 99,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L99"
|
||||
"lineNumber": 91,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L91"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1138,15 +1132,15 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 99,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L99"
|
||||
"lineNumber": 91,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L91"
|
||||
}
|
||||
}
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 99,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L99"
|
||||
"lineNumber": 91,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L91"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -1154,8 +1148,8 @@
|
|||
"returnComment": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 99,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L99"
|
||||
"lineNumber": 91,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L91"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1177,8 +1171,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 101,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L101"
|
||||
"lineNumber": 93,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L93"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1191,8 +1185,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 102,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L102"
|
||||
"lineNumber": 94,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L94"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1210,15 +1204,15 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 103,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L103"
|
||||
"lineNumber": 95,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L95"
|
||||
}
|
||||
}
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 103,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L103"
|
||||
"lineNumber": 95,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L95"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -1226,8 +1220,8 @@
|
|||
"returnComment": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 100,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L100"
|
||||
"lineNumber": 92,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L92"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1272,8 +1266,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 105,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L105"
|
||||
"lineNumber": 97,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L97"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -1281,8 +1275,8 @@
|
|||
"returnComment": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 105,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L105"
|
||||
"lineNumber": 97,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L97"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1327,8 +1321,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 106,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L106"
|
||||
"lineNumber": 98,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L98"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -1336,8 +1330,8 @@
|
|||
"returnComment": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 106,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L106"
|
||||
"lineNumber": 98,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L98"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1348,8 +1342,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 107,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L107"
|
||||
"lineNumber": 99,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L99"
|
||||
},
|
||||
"signature": [
|
||||
{
|
||||
|
@ -1381,8 +1375,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 109,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L109"
|
||||
"lineNumber": 101,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L101"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1395,8 +1389,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 110,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L110"
|
||||
"lineNumber": 102,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L102"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1409,8 +1403,8 @@
|
|||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 111,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L111"
|
||||
"lineNumber": 103,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L103"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -1418,15 +1412,15 @@
|
|||
"returnComment": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 108,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L108"
|
||||
"lineNumber": 100,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L100"
|
||||
}
|
||||
}
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/actions/server/plugin.ts",
|
||||
"lineNumber": 98,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L98"
|
||||
"lineNumber": 90,
|
||||
"link": "https://github.com/elastic/kibana/tree/masterx-pack/plugins/actions/server/plugin.ts#L90"
|
||||
},
|
||||
"lifecycle": "start",
|
||||
"initialIsOpen": true
|
||||
|
|
|
@ -3,21 +3,23 @@
|
|||
|
||||
Manage Actions and Connectors.
|
||||
|
||||
The following action APIs are available:
|
||||
The following connector APIs are available:
|
||||
|
||||
* <<actions-and-connectors-api-get, Get action API>> to retrieve a single action by ID
|
||||
* <<actions-and-connectors-api-get, Get connector API>> to retrieve a single connector by ID
|
||||
|
||||
* <<actions-and-connectors-api-get-all, Get all actions API>> to retrieve all actions
|
||||
* <<actions-and-connectors-api-get-all, Get all connectors API>> to retrieve all connectors
|
||||
|
||||
* <<actions-and-connectors-api-list, List all action types API>> to retrieve a list of all action types
|
||||
* <<actions-and-connectors-api-list, List all connector types API>> to retrieve a list of all connector types
|
||||
|
||||
* <<actions-and-connectors-api-create, Create action API>> to create actions
|
||||
* <<actions-and-connectors-api-create, Create connector API>> to create connectors
|
||||
|
||||
* <<actions-and-connectors-api-update, Update action API>> to update the attributes for an existing action
|
||||
* <<actions-and-connectors-api-update, Update connector API>> to update the attributes for an existing connector
|
||||
|
||||
* <<actions-and-connectors-api-execute, Execute action API>> to execute an action by ID
|
||||
* <<actions-and-connectors-api-execute, Execute connector API>> to execute a connector by ID
|
||||
|
||||
* <<actions-and-connectors-api-delete, Delete action API>> to delete an action by ID
|
||||
* <<actions-and-connectors-api-delete, Delete connector API>> to delete a connector by ID
|
||||
|
||||
For deprecated APIs, refer to <<actions-and-connectors-legacy-apis>>.
|
||||
|
||||
For information about the actions and connectors that {kib} supports, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
|
@ -28,3 +30,11 @@ include::actions-and-connectors/create.asciidoc[]
|
|||
include::actions-and-connectors/update.asciidoc[]
|
||||
include::actions-and-connectors/execute.asciidoc[]
|
||||
include::actions-and-connectors/delete.asciidoc[]
|
||||
include::actions-and-connectors/legacy/index.asciidoc[]
|
||||
include::actions-and-connectors/legacy/get.asciidoc[]
|
||||
include::actions-and-connectors/legacy/get_all.asciidoc[]
|
||||
include::actions-and-connectors/legacy/list.asciidoc[]
|
||||
include::actions-and-connectors/legacy/create.asciidoc[]
|
||||
include::actions-and-connectors/legacy/update.asciidoc[]
|
||||
include::actions-and-connectors/legacy/execute.asciidoc[]
|
||||
include::actions-and-connectors/legacy/delete.asciidoc[]
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
[[actions-and-connectors-api-create]]
|
||||
=== Create action API
|
||||
=== Create connector API
|
||||
++++
|
||||
<titleabbrev>Create action API</titleabbrev>
|
||||
<titleabbrev>Create connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
Creates an action.
|
||||
Creates a connector.
|
||||
|
||||
[[actions-and-connectors-api-create-request]]
|
||||
==== Request
|
||||
|
||||
`POST <kibana host>:<port>/api/actions/action`
|
||||
`POST <kibana host>:<port>/api/actions/connector`
|
||||
|
||||
`POST <kibana host>:<port>/s/<space_id>/api/actions/action`
|
||||
`POST <kibana host>:<port>/s/<space_id>/api/actions/connector`
|
||||
|
||||
[[actions-and-connectors-api-create-path-params]]
|
||||
==== Path parameters
|
||||
|
@ -23,18 +23,18 @@ Creates an action.
|
|||
==== Request body
|
||||
|
||||
`name`::
|
||||
(Required, string) The display name for the action.
|
||||
(Required, string) The display name for the connector.
|
||||
|
||||
`actionTypeId`::
|
||||
(Required, string) The action type ID for the action.
|
||||
`connector_type_id`::
|
||||
(Required, string) The connector type ID for the connector.
|
||||
|
||||
`config`::
|
||||
(Required, object) The configuration for the action. Configuration properties vary depending on
|
||||
the action type. For information about the configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
(Required, object) The configuration for the connector. Configuration properties vary depending on
|
||||
the connector type. For information about the configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
`secrets`::
|
||||
(Required, object) The secrets configuration for the action. Secrets configuration properties vary
|
||||
depending on the action type. For information about the secrets configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
(Required, object) The secrets configuration for the connector. Secrets configuration properties vary
|
||||
depending on the connector type. For information about the secrets configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
+
|
||||
WARNING: Remember these values. You must provide them each time you call the <<actions-and-connectors-api-update, update>> API.
|
||||
|
||||
|
@ -49,10 +49,10 @@ WARNING: Remember these values. You must provide them each time you call the <<a
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X POST api/actions/action -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
$ curl -X POST api/actions/connector -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
{
|
||||
"name": "my-action",
|
||||
"actionTypeId": ".index",
|
||||
"name": "my-connector",
|
||||
"connector_type_id": ".index",
|
||||
"config": {
|
||||
"index": "test-index"
|
||||
}
|
||||
|
@ -66,13 +66,13 @@ The API returns the following:
|
|||
--------------------------------------------------
|
||||
{
|
||||
"id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad",
|
||||
"actionTypeId": ".index",
|
||||
"name": "my-action",
|
||||
"connector_type_id": ".index",
|
||||
"name": "my-connector",
|
||||
"config": {
|
||||
"index": "test-index",
|
||||
"refresh": false,
|
||||
"executionTimeField": null
|
||||
},
|
||||
"isPreconfigured": false
|
||||
"is_preconfigured": false
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
[[actions-and-connectors-api-delete]]
|
||||
=== Delete action API
|
||||
=== Delete connector API
|
||||
++++
|
||||
<titleabbrev>Delete action API</titleabbrev>
|
||||
<titleabbrev>Delete connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
Deletes an action by ID.
|
||||
Deletes an connector by ID.
|
||||
|
||||
WARNING: When you delete an action, _it cannot be recovered_.
|
||||
WARNING: When you delete a connector, _it cannot be recovered_.
|
||||
|
||||
[[actions-and-connectors-api-delete-request]]
|
||||
==== Request
|
||||
|
||||
`DELETE <kibana host>:<port>/api/actions/action/<id>`
|
||||
`DELETE <kibana host>:<port>/api/actions/connector/<id>`
|
||||
|
||||
`DELETE <kibana host>:<port>/s/<space_id>/api/actions/action/<id>`
|
||||
`DELETE <kibana host>:<port>/s/<space_id>/api/actions/connector/<id>`
|
||||
|
||||
[[actions-and-connectors-api-delete-path-params]]
|
||||
==== Path parameters
|
||||
|
||||
`id`::
|
||||
(Required, string) The ID of the action.
|
||||
(Required, string) The ID of the connector.
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
@ -34,6 +34,6 @@ WARNING: When you delete an action, _it cannot be recovered_.
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X DELETE api/actions/action/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad
|
||||
$ curl -X DELETE api/actions/connector/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
[[actions-and-connectors-api-execute]]
|
||||
=== Execute action API
|
||||
=== Execute connector API
|
||||
++++
|
||||
<titleabbrev>Execute action API</titleabbrev>
|
||||
<titleabbrev>Execute connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
Executes an action by ID.
|
||||
Executes a connector by ID.
|
||||
|
||||
[[actions-and-connectors-api-execute-request]]
|
||||
==== Request
|
||||
|
||||
`POST <kibana host>:<port>/api/actions/action/<id>/_execute`
|
||||
`POST <kibana host>:<port>/api/actions/connector/<id>/_execute`
|
||||
|
||||
`POST <kibana host>:<port>/s/<space_id>/api/actions/action/<id>/_execute`
|
||||
`POST <kibana host>:<port>/s/<space_id>/api/actions/connector/<id>/_execute`
|
||||
|
||||
[[actions-and-connectors-api-execute-params]]
|
||||
==== Path parameters
|
||||
|
||||
`id`::
|
||||
(Required, string) The ID of the action.
|
||||
(Required, string) The ID of the connector.
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
@ -26,8 +26,8 @@ Executes an action by ID.
|
|||
==== Request body
|
||||
|
||||
`params`::
|
||||
(Required, object) The parameters of the action. Parameter properties vary depending on
|
||||
the action type. For information about the parameter properties, refer to <<action-types,Action and connector types>>.
|
||||
(Required, object) The parameters of the connector. Parameter properties vary depending on
|
||||
the connector type. For information about the parameter properties, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
[[actions-and-connectors-api-execute-codes]]
|
||||
==== Response code
|
||||
|
@ -40,7 +40,7 @@ Executes an action by ID.
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X POST api/actions/action/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad/_execute -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
$ curl -X POST api/actions/connector/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad/_execute -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
{
|
||||
"params": {
|
||||
"documents": [
|
||||
|
@ -83,6 +83,6 @@ The API returns the following:
|
|||
}
|
||||
]
|
||||
},
|
||||
"actionId": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad"
|
||||
"connector_id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad"
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
[[actions-and-connectors-api-get]]
|
||||
=== Get action API
|
||||
=== Get connector API
|
||||
++++
|
||||
<titleabbrev>Get action API</titleabbrev>
|
||||
<titleabbrev>Get connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
Retrieves an action by ID.
|
||||
Retrieves a connector by ID.
|
||||
|
||||
[[actions-and-connectors-api-get-request]]
|
||||
==== Request
|
||||
|
||||
`GET <kibana host>:<port>/api/actions/action/<id>`
|
||||
`GET <kibana host>:<port>/api/actions/connector/<id>`
|
||||
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions/action/<id>`
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions/connector/<id>`
|
||||
|
||||
[[actions-and-connectors-api-get-params]]
|
||||
==== Path parameters
|
||||
|
||||
`id`::
|
||||
(Required, string) The ID of the action.
|
||||
(Required, string) The ID of the connector.
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
@ -33,7 +33,7 @@ Retrieves an action by ID.
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X GET api/actions/action/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad
|
||||
$ curl -X GET api/actions/connector/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
|
@ -43,13 +43,13 @@ The API returns the following:
|
|||
--------------------------------------------------
|
||||
{
|
||||
"id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad",
|
||||
"actionTypeId": ".index",
|
||||
"name": "my-action",
|
||||
"connector_type_id": ".index",
|
||||
"name": "my-connector",
|
||||
"config": {
|
||||
"index": "test-index",
|
||||
"refresh": false,
|
||||
"executionTimeField": null
|
||||
},
|
||||
"isPreconfigured": false
|
||||
"is_preconfigured": false
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
<titleabbrev>Get all actions API</titleabbrev>
|
||||
++++
|
||||
|
||||
Retrieves all actions.
|
||||
Retrieves all connectors.
|
||||
|
||||
[[actions-and-connectors-api-get-all-request]]
|
||||
==== Request
|
||||
|
||||
`GET <kibana host>:<port>/api/actions`
|
||||
`GET <kibana host>:<port>/api/actions/connectors`
|
||||
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions`
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions/connectors`
|
||||
|
||||
[[actions-and-connectors-api-get-all-path-params]]
|
||||
==== Path parameters
|
||||
|
@ -30,7 +30,7 @@ Retrieves all actions.
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X GET api/actions
|
||||
$ curl -X GET api/actions/connectors
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
|
@ -40,21 +40,23 @@ The API returns the following:
|
|||
--------------------------------------------------
|
||||
[
|
||||
{
|
||||
"id": "preconfigured-mail-action",
|
||||
"actionTypeId": ".email",
|
||||
"name": "email: preconfigured-mail-action",
|
||||
"isPreconfigured": true
|
||||
"id": "preconfigured-mail-connector",
|
||||
"connector_type_id": ".email",
|
||||
"name": "email: preconfigured-mail-connector",
|
||||
"is_preconfigured": true,
|
||||
"referenced_by_count": 1
|
||||
},
|
||||
{
|
||||
"id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad",
|
||||
"actionTypeId": ".index",
|
||||
"name": "my-action",
|
||||
"connector_type_id": ".index",
|
||||
"name": "my-connector",
|
||||
"config": {
|
||||
"index": "test-index",
|
||||
"refresh": false,
|
||||
"executionTimeField": null
|
||||
},
|
||||
"isPreconfigured": false
|
||||
"is_preconfigured": false,
|
||||
"referenced_by_count": 3
|
||||
}
|
||||
]
|
||||
--------------------------------------------------
|
||||
|
|
82
docs/api/actions-and-connectors/legacy/create.asciidoc
Normal file
82
docs/api/actions-and-connectors/legacy/create.asciidoc
Normal file
|
@ -0,0 +1,82 @@
|
|||
[[actions-and-connectors-legacy-api-create]]
|
||||
==== Legacy Create connector API
|
||||
++++
|
||||
<titleabbrev>Legacy Create connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
deprecated::[7.13.0]
|
||||
|
||||
Please use the <<actions-and-connectors-api-create>> instead.
|
||||
|
||||
Creates a connector.
|
||||
|
||||
[[actions-and-connectors-legacy-api-create-request]]
|
||||
===== Request
|
||||
|
||||
`POST <kibana host>:<port>/api/actions/action`
|
||||
|
||||
`POST <kibana host>:<port>/s/<space_id>/api/actions/action`
|
||||
|
||||
[[actions-and-connectors-legacy-api-create-path-params]]
|
||||
===== Path parameters
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
[[actions-and-connectors-legacy-api-create-request-body]]
|
||||
===== Request body
|
||||
|
||||
`name`::
|
||||
(Required, string) The display name for the connector.
|
||||
|
||||
`actionTypeId`::
|
||||
(Required, string) The connector type ID for the connector.
|
||||
|
||||
`config`::
|
||||
(Required, object) The configuration for the connector. Configuration properties vary depending on
|
||||
the connector type. For information about the configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
`secrets`::
|
||||
(Required, object) The secrets configuration for the connector. Secrets configuration properties vary
|
||||
depending on the connector type. For information about the secrets configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
+
|
||||
WARNING: Remember these values. You must provide them each time you call the <<actions-and-connectors-legacy-api-update, update>> API.
|
||||
|
||||
[[actions-and-connectors-legacy-api-create-request-codes]]
|
||||
===== Response code
|
||||
|
||||
`200`::
|
||||
Indicates a successful call.
|
||||
|
||||
[[actions-and-connectors-legacy-api-create-example]]
|
||||
===== Example
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X POST api/actions/action -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
{
|
||||
"name": "my-connector",
|
||||
"actionTypeId": ".index",
|
||||
"config": {
|
||||
"index": "test-index"
|
||||
}
|
||||
}'
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns the following:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad",
|
||||
"actionTypeId": ".index",
|
||||
"name": "my-connector",
|
||||
"config": {
|
||||
"index": "test-index",
|
||||
"refresh": false,
|
||||
"executionTimeField": null
|
||||
},
|
||||
"isPreconfigured": false
|
||||
}
|
||||
--------------------------------------------------
|
43
docs/api/actions-and-connectors/legacy/delete.asciidoc
Normal file
43
docs/api/actions-and-connectors/legacy/delete.asciidoc
Normal file
|
@ -0,0 +1,43 @@
|
|||
[[actions-and-connectors-legacy-api-delete]]
|
||||
==== Legacy Delete connector API
|
||||
++++
|
||||
<titleabbrev>Legacy Delete connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
deprecated::[7.13.0]
|
||||
|
||||
Please use the <<actions-and-connectors-api-delete>> instead.
|
||||
|
||||
Deletes a connector by ID.
|
||||
|
||||
WARNING: When you delete an connector, _it cannot be recovered_.
|
||||
|
||||
[[actions-and-connectors-legacy-api-delete-request]]
|
||||
===== Request
|
||||
|
||||
`DELETE <kibana host>:<port>/api/actions/action/<id>`
|
||||
|
||||
`DELETE <kibana host>:<port>/s/<space_id>/api/actions/action/<id>`
|
||||
|
||||
[[actions-and-connectors-legacy-api-delete-path-params]]
|
||||
===== Path parameters
|
||||
|
||||
`id`::
|
||||
(Required, string) The ID of the connector.
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
[[actions-and-connectors-legacy-api-delete-response-codes]]
|
||||
===== Response code
|
||||
|
||||
`200`::
|
||||
Indicates a successful call.
|
||||
|
||||
===== Example
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X DELETE api/actions/action/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
92
docs/api/actions-and-connectors/legacy/execute.asciidoc
Normal file
92
docs/api/actions-and-connectors/legacy/execute.asciidoc
Normal file
|
@ -0,0 +1,92 @@
|
|||
[[actions-and-connectors-legacy-api-execute]]
|
||||
==== Legacy Execute connector API
|
||||
++++
|
||||
<titleabbrev>Legacy Execute connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
deprecated::[7.13.0]
|
||||
|
||||
Please use the <<actions-and-connectors-api-execute>> instead.
|
||||
|
||||
Executes a connector by ID.
|
||||
|
||||
[[actions-and-connectors-legacy-api-execute-request]]
|
||||
===== Request
|
||||
|
||||
`POST <kibana host>:<port>/api/actions/action/<id>/_execute`
|
||||
|
||||
`POST <kibana host>:<port>/s/<space_id>/api/actions/action/<id>/_execute`
|
||||
|
||||
[[actions-and-connectors-legacy-api-execute-params]]
|
||||
===== Path parameters
|
||||
|
||||
`id`::
|
||||
(Required, string) The ID of the connector.
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
[[actions-and-connectors-legacy-api-execute-request-body]]
|
||||
===== Request body
|
||||
|
||||
`params`::
|
||||
(Required, object) The parameters of the connector. Parameter properties vary depending on
|
||||
the connector type. For information about the parameter properties, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
[[actions-and-connectors-legacy-api-execute-codes]]
|
||||
===== Response code
|
||||
|
||||
`200`::
|
||||
Indicates a successful call.
|
||||
|
||||
[[actions-and-connectors-legacy-api-execute-example]]
|
||||
===== Example
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X POST api/actions/action/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad/_execute -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
{
|
||||
"params": {
|
||||
"documents": [
|
||||
{
|
||||
"id": "test_doc_id",
|
||||
"name": "test_doc_name",
|
||||
"message": "hello, world"
|
||||
}
|
||||
]
|
||||
}
|
||||
}'
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns the following:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"status": "ok",
|
||||
"data": {
|
||||
"took": 197,
|
||||
"errors": false,
|
||||
"items": [
|
||||
{
|
||||
"index": {
|
||||
"_index": "updated-index",
|
||||
"_id": "iKyijHcBKCsmXNFrQe3T",
|
||||
"_version": 1,
|
||||
"result": "created",
|
||||
"_shards": {
|
||||
"total": 2,
|
||||
"successful": 1,
|
||||
"failed": 0
|
||||
},
|
||||
"_seq_no": 0,
|
||||
"_primary_term": 1,
|
||||
"status": 201
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"actionId": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad"
|
||||
}
|
||||
--------------------------------------------------
|
59
docs/api/actions-and-connectors/legacy/get.asciidoc
Normal file
59
docs/api/actions-and-connectors/legacy/get.asciidoc
Normal file
|
@ -0,0 +1,59 @@
|
|||
[[actions-and-connectors-legacy-api-get]]
|
||||
==== Legacy Get connector API
|
||||
++++
|
||||
<titleabbrev>Legacy Get connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
deprecated::[7.13.0]
|
||||
|
||||
Please use the <<actions-and-connectors-api-get>> instead.
|
||||
|
||||
Retrieves a connector by ID.
|
||||
|
||||
[[actions-and-connectors-legacy-api-get-request]]
|
||||
===== Request
|
||||
|
||||
`GET <kibana host>:<port>/api/actions/action/<id>`
|
||||
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions/action/<id>`
|
||||
|
||||
[[actions-and-connectors-legacy-api-get-params]]
|
||||
===== Path parameters
|
||||
|
||||
`id`::
|
||||
(Required, string) The ID of the action.
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
[[actions-and-connectors-legacy-api-get-codes]]
|
||||
===== Response code
|
||||
|
||||
`200`::
|
||||
Indicates a successful call.
|
||||
|
||||
[[actions-and-connectors-legacy-api-get-example]]
|
||||
===== Example
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X GET api/actions/action/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns the following:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad",
|
||||
"actionTypeId": ".index",
|
||||
"name": "my-connector",
|
||||
"config": {
|
||||
"index": "test-index",
|
||||
"refresh": false,
|
||||
"executionTimeField": null
|
||||
},
|
||||
"isPreconfigured": false
|
||||
}
|
||||
--------------------------------------------------
|
64
docs/api/actions-and-connectors/legacy/get_all.asciidoc
Normal file
64
docs/api/actions-and-connectors/legacy/get_all.asciidoc
Normal file
|
@ -0,0 +1,64 @@
|
|||
[[actions-and-connectors-legacy-api-get-all]]
|
||||
==== Legacy Get all connector API
|
||||
++++
|
||||
<titleabbrev>Legacy Get all connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
deprecated::[7.13.0]
|
||||
|
||||
Please use the <<actions-and-connectors-api-get-all>> instead.
|
||||
|
||||
Retrieves all connectors.
|
||||
|
||||
[[actions-and-connectors-legacy-api-get-all-request]]
|
||||
===== Request
|
||||
|
||||
`GET <kibana host>:<port>/api/actions`
|
||||
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions`
|
||||
|
||||
[[actions-and-connectors-legacy-api-get-all-path-params]]
|
||||
===== Path parameters
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
[[actions-and-connectors-legacy-api-get-all-codes]]
|
||||
===== Response code
|
||||
|
||||
`200`::
|
||||
Indicates a successful call.
|
||||
|
||||
[[actions-and-connectors-legacy-api-get-all-example]]
|
||||
===== Example
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X GET api/actions
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns the following:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
[
|
||||
{
|
||||
"id": "preconfigured-mail-action",
|
||||
"actionTypeId": ".email",
|
||||
"name": "email: preconfigured-mail-action",
|
||||
"isPreconfigured": true
|
||||
},
|
||||
{
|
||||
"id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad",
|
||||
"actionTypeId": ".index",
|
||||
"name": "my-action",
|
||||
"config": {
|
||||
"index": "test-index",
|
||||
"refresh": false,
|
||||
"executionTimeField": null
|
||||
},
|
||||
"isPreconfigured": false
|
||||
}
|
||||
]
|
||||
--------------------------------------------------
|
4
docs/api/actions-and-connectors/legacy/index.asciidoc
Normal file
4
docs/api/actions-and-connectors/legacy/index.asciidoc
Normal file
|
@ -0,0 +1,4 @@
|
|||
[[actions-and-connectors-legacy-apis]]
|
||||
=== Deprecated 7.x APIs
|
||||
|
||||
These APIs are deprecated and will be removed as of 8.0.
|
71
docs/api/actions-and-connectors/legacy/list.asciidoc
Normal file
71
docs/api/actions-and-connectors/legacy/list.asciidoc
Normal file
|
@ -0,0 +1,71 @@
|
|||
[[actions-and-connectors-legacy-api-list]]
|
||||
==== Legacy List connector types API
|
||||
++++
|
||||
<titleabbrev>Legacy List all connector types API</titleabbrev>
|
||||
++++
|
||||
|
||||
deprecated::[7.13.0]
|
||||
|
||||
Please use the <<actions-and-connectors-api-list>> instead.
|
||||
|
||||
Retrieves a list of all connector types.
|
||||
|
||||
[[actions-and-connectors-legacy-api-list-request]]
|
||||
===== Request
|
||||
|
||||
`GET <kibana host>:<port>/api/actions/list_action_types`
|
||||
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions/list_action_types`
|
||||
|
||||
[[actions-and-connectors-legacy-api-list-path-params]]
|
||||
===== Path parameters
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
[[actions-and-connectors-legacy-api-list-codes]]
|
||||
===== Response code
|
||||
|
||||
`200`::
|
||||
Indicates a successful call.
|
||||
|
||||
[[actions-and-connectors-legacy-api-list-example]]
|
||||
===== Example
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X GET api/actions/list_action_types
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns the following:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
[
|
||||
{
|
||||
"id": ".email", <1>
|
||||
"name": "Email", <2>
|
||||
"minimumLicenseRequired": "gold", <3>
|
||||
"enabled": false, <4>
|
||||
"enabledInConfig": true, <5>
|
||||
"enabledInLicense": false <6>
|
||||
},
|
||||
{
|
||||
"id": ".index",
|
||||
"name": "Index",
|
||||
"minimumLicenseRequired": "basic",
|
||||
"enabled": true,
|
||||
"enabledInConfig": true,
|
||||
"enabledInLicense": true
|
||||
}
|
||||
]
|
||||
--------------------------------------------------
|
||||
|
||||
|
||||
<1> `id` - The unique ID of the connector type.
|
||||
<2> `name` - The name of the connector type.
|
||||
<3> `minimumLicenseRequired` - The license required to use the connector type.
|
||||
<4> `enabled` - Specifies if the connector type is enabled or disabled in {kib}.
|
||||
<5> `enabledInConfig` - Specifies if the connector type is enabled or enabled in the {kib} .yml file.
|
||||
<6> `enabledInLicense` - Specifies if the connector type is enabled or disabled in the license.
|
77
docs/api/actions-and-connectors/legacy/update.asciidoc
Normal file
77
docs/api/actions-and-connectors/legacy/update.asciidoc
Normal file
|
@ -0,0 +1,77 @@
|
|||
[[actions-and-connectors-legacy-api-update]]
|
||||
==== Legacy Update connector API
|
||||
++++
|
||||
<titleabbrev>Legacy Update connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
deprecated::[7.13.0]
|
||||
|
||||
Please use the <<actions-and-connectors-api-update>> instead.
|
||||
|
||||
Updates the attributes for an existing connector.
|
||||
|
||||
[[actions-and-connectors-legacy-api-update-request]]
|
||||
===== Request
|
||||
|
||||
`PUT <kibana host>:<port>/api/actions/action/<id>`
|
||||
|
||||
`PUT <kibana host>:<port>/s/<space_id>/api/actions/action/<id>`
|
||||
|
||||
[[actions-and-connectors-legacy-api-update-params]]
|
||||
===== Path parameters
|
||||
|
||||
`id`::
|
||||
(Required, string) The ID of the connector.
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
[[actions-and-connectors-legacy-api-update-request-body]]
|
||||
===== Request body
|
||||
|
||||
`name`::
|
||||
(Required, string) The new name of the connector.
|
||||
|
||||
`config`::
|
||||
(Required, object) The new connector configuration. Configuration properties vary depending on the connector type. For information about the configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
`secrets`::
|
||||
(Required, object) The updated secrets configuration for the connector. Secrets properties vary depending on the connector type. For information about the secrets configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
[[actions-and-connectors-legacy-api-update-codes]]
|
||||
===== Response code
|
||||
|
||||
`200`::
|
||||
Indicates a successful call.
|
||||
|
||||
[[actions-and-connectors-legacy-api-update-example]]
|
||||
===== Example
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X PUT api/actions/action/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
{
|
||||
"name": "updated-connector",
|
||||
"config": {
|
||||
"index": "updated-index"
|
||||
}
|
||||
}'
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns the following:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad",
|
||||
"actionTypeId": ".index",
|
||||
"name": "updated-connector",
|
||||
"config": {
|
||||
"index": "updated-index",
|
||||
"refresh": false,
|
||||
"executionTimeField": null
|
||||
},
|
||||
"isPreconfigured": false
|
||||
}
|
||||
--------------------------------------------------
|
|
@ -1,17 +1,17 @@
|
|||
[[actions-and-connectors-api-list]]
|
||||
=== List action types API
|
||||
=== List connector types API
|
||||
++++
|
||||
<titleabbrev>List all action types API</titleabbrev>
|
||||
<titleabbrev>List all connector types API</titleabbrev>
|
||||
++++
|
||||
|
||||
Retrieves a list of all action types.
|
||||
Retrieves a list of all connector types.
|
||||
|
||||
[[actions-and-connectors-api-list-request]]
|
||||
==== Request
|
||||
|
||||
`GET <kibana host>:<port>/api/actions/list_action_types`
|
||||
`GET <kibana host>:<port>/api/actions/connector_types`
|
||||
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions/list_action_types`
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/actions/connector_types`
|
||||
|
||||
[[actions-and-connectors-api-list-path-params]]
|
||||
==== Path parameters
|
||||
|
@ -30,7 +30,7 @@ Retrieves a list of all action types.
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X GET api/actions/list_action_types
|
||||
$ curl -X GET api/actions/connector_types
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
|
@ -42,26 +42,26 @@ The API returns the following:
|
|||
{
|
||||
"id": ".email", <1>
|
||||
"name": "Email", <2>
|
||||
"minimumLicenseRequired": "gold", <3>
|
||||
"minimum_license_required": "gold", <3>
|
||||
"enabled": false, <4>
|
||||
"enabledInConfig": true, <5>
|
||||
"enabledInLicense": false <6>
|
||||
"enabled_in_config": true, <5>
|
||||
"enabled_in_license": false <6>
|
||||
},
|
||||
{
|
||||
"id": ".index",
|
||||
"name": "Index",
|
||||
"minimumLicenseRequired": "basic",
|
||||
"minimum_license_required": "basic",
|
||||
"enabled": true,
|
||||
"enabledInConfig": true,
|
||||
"enabledInLicense": true
|
||||
"enabled_in_config": true,
|
||||
"enabled_in_license": true
|
||||
}
|
||||
]
|
||||
--------------------------------------------------
|
||||
|
||||
|
||||
<1> `id` - The unique ID of the action type.
|
||||
<2> `name` - The name of the action type.
|
||||
<3> `minimumLicenseRequired` - The license required to use the action type.
|
||||
<4> `enabled` - Specifies if the action type is enabled or disabled in {kib}.
|
||||
<5> `enabledInConfig` - Specifies if the action type is enabled or enabled in the {kib} .yml file.
|
||||
<6> `enabledInLicense` - Specifies if the action type is enabled or disabled in the license.
|
||||
<1> `id` - The unique ID of the connector type.
|
||||
<2> `name` - The name of the connector type.
|
||||
<3> `minimum_license_required` - The license required to use the connector type.
|
||||
<4> `enabled` - Specifies if the connector type is enabled or disabled in {kib}.
|
||||
<5> `enabled_in_config` - Specifies if the connector type is enabled or enabled in the {kib} .yml file.
|
||||
<6> `enabled_in_license` - Specifies if the connector type is enabled or disabled in the license.
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
[[actions-and-connectors-api-update]]
|
||||
=== Update action API
|
||||
=== Update connector API
|
||||
++++
|
||||
<titleabbrev>Update action API</titleabbrev>
|
||||
<titleabbrev>Update connector API</titleabbrev>
|
||||
++++
|
||||
|
||||
Updates the attributes for an existing action.
|
||||
Updates the attributes for an existing connector.
|
||||
|
||||
[[actions-and-connectors-api-update-request]]
|
||||
==== Request
|
||||
|
||||
`PUT <kibana host>:<port>/api/actions/action/<id>`
|
||||
`PUT <kibana host>:<port>/api/actions/connector/<id>`
|
||||
|
||||
`PUT <kibana host>:<port>/s/<space_id>/api/actions/action/<id>`
|
||||
`PUT <kibana host>:<port>/s/<space_id>/api/actions/connector/<id>`
|
||||
|
||||
[[actions-and-connectors-api-update-params]]
|
||||
==== Path parameters
|
||||
|
||||
`id`::
|
||||
(Required, string) The ID of the action.
|
||||
(Required, string) The ID of the connector.
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
@ -26,13 +26,13 @@ Updates the attributes for an existing action.
|
|||
==== Request body
|
||||
|
||||
`name`::
|
||||
(Required, string) The new name of the action.
|
||||
(Required, string) The new name of the connector.
|
||||
|
||||
`config`::
|
||||
(Required, object) The new action configuration. Configuration properties vary depending on the action type. For information about the configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
(Required, object) The new connector configuration. Configuration properties vary depending on the connector type. For information about the configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
`secrets`::
|
||||
(Required, object) The updated secrets configuration for the action. Secrets properties vary depending on the action type. For information about the secrets configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
(Required, object) The updated secrets configuration for the connector. Secrets properties vary depending on the connector type. For information about the secrets configuration properties, refer to <<action-types,Action and connector types>>.
|
||||
|
||||
[[actions-and-connectors-api-update-codes]]
|
||||
==== Response code
|
||||
|
@ -45,9 +45,9 @@ Updates the attributes for an existing action.
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X PUT api/actions/action/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
$ curl -X PUT api/actions/connector/c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '
|
||||
{
|
||||
"name": "updated-action",
|
||||
"name": "updated-connector",
|
||||
"config": {
|
||||
"index": "updated-index"
|
||||
}
|
||||
|
@ -61,13 +61,13 @@ The API returns the following:
|
|||
--------------------------------------------------
|
||||
{
|
||||
"id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad",
|
||||
"actionTypeId": ".index",
|
||||
"name": "updated-action",
|
||||
"connector_type_id": ".index",
|
||||
"name": "updated-connector",
|
||||
"config": {
|
||||
"index": "updated-index",
|
||||
"refresh": false,
|
||||
"executionTimeField": null
|
||||
},
|
||||
"isPreconfigured": false
|
||||
"is_preconfigured": false
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
|
|
@ -56,7 +56,7 @@ interface Action extends ActionUpdate {
|
|||
actionTypeId: string;
|
||||
}
|
||||
|
||||
interface CreateOptions {
|
||||
export interface CreateOptions {
|
||||
action: Action;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ interface ConstructorOptions {
|
|||
auditLogger?: AuditLogger;
|
||||
}
|
||||
|
||||
interface UpdateOptions {
|
||||
export interface UpdateOptions {
|
||||
id: string;
|
||||
action: ActionUpdate;
|
||||
}
|
||||
|
|
|
@ -50,15 +50,7 @@ import {
|
|||
|
||||
import { getActionsConfigurationUtilities } from './actions_config';
|
||||
|
||||
import {
|
||||
createActionRoute,
|
||||
deleteActionRoute,
|
||||
getAllActionRoute,
|
||||
getActionRoute,
|
||||
updateActionRoute,
|
||||
listActionTypesRoute,
|
||||
executeActionRoute,
|
||||
} from './routes';
|
||||
import { defineRoutes } from './routes';
|
||||
import { IEventLogger, IEventLogService } from '../../event_log/server';
|
||||
import { initializeActionsTelemetry, scheduleActionsTelemetry } from './usage/task';
|
||||
import {
|
||||
|
@ -237,14 +229,7 @@ export class ActionsPlugin implements Plugin<PluginSetupContract, PluginStartCon
|
|||
}
|
||||
|
||||
// Routes
|
||||
const router = core.http.createRouter<ActionsRequestHandlerContext>();
|
||||
createActionRoute(router, this.licenseState);
|
||||
deleteActionRoute(router, this.licenseState);
|
||||
getActionRoute(router, this.licenseState);
|
||||
getAllActionRoute(router, this.licenseState);
|
||||
updateActionRoute(router, this.licenseState);
|
||||
listActionTypesRoute(router, this.licenseState);
|
||||
executeActionRoute(router, this.licenseState);
|
||||
defineRoutes(core.http.createRouter<ActionsRequestHandlerContext>(), this.licenseState);
|
||||
|
||||
return {
|
||||
registerType: <
|
||||
|
|
157
x-pack/plugins/actions/server/routes/connector_types.test.ts
Normal file
157
x-pack/plugins/actions/server/routes/connector_types.test.ts
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { connectorTypesRoute } from './connector_types';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { mockHandlerArguments } from './legacy/_mock_handler_arguments';
|
||||
import { LicenseType } from '../../../../plugins/licensing/server';
|
||||
import { actionsClientMock } from '../mocks';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
|
||||
jest.mock('./verify_access_and_context.ts', () => ({
|
||||
verifyAccessAndContext: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation((license, handler) => handler);
|
||||
});
|
||||
|
||||
describe('connectorTypesRoute', () => {
|
||||
it('lists action types with proper parameters', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
connectorTypesRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connector_types"`);
|
||||
|
||||
const listTypes = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'name',
|
||||
enabled: true,
|
||||
enabledInConfig: true,
|
||||
enabledInLicense: true,
|
||||
minimumLicenseRequired: 'gold' as LicenseType,
|
||||
},
|
||||
];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.listTypes.mockResolvedValueOnce(listTypes);
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']);
|
||||
|
||||
expect(await handler(context, req, res)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"body": Array [
|
||||
Object {
|
||||
"enabled": true,
|
||||
"enabled_in_config": true,
|
||||
"enabled_in_license": true,
|
||||
"id": "1",
|
||||
"minimum_license_required": "gold",
|
||||
"name": "name",
|
||||
},
|
||||
],
|
||||
}
|
||||
`);
|
||||
|
||||
expect(res.ok).toHaveBeenCalledWith({
|
||||
body: [
|
||||
{
|
||||
id: '1',
|
||||
name: 'name',
|
||||
enabled: true,
|
||||
enabled_in_config: true,
|
||||
enabled_in_license: true,
|
||||
minimum_license_required: 'gold',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures the license allows listing action types', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
connectorTypesRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connector_types"`);
|
||||
|
||||
const listTypes = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'name',
|
||||
enabled: true,
|
||||
enabledInConfig: true,
|
||||
enabledInLicense: true,
|
||||
minimumLicenseRequired: 'gold' as LicenseType,
|
||||
},
|
||||
];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.listTypes.mockResolvedValueOnce(listTypes);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: { id: '1' },
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
|
||||
it('ensures the license check prevents listing action types', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
connectorTypesRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connector_types"`);
|
||||
|
||||
const listTypes = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'name',
|
||||
enabled: true,
|
||||
enabledInConfig: true,
|
||||
enabledInLicense: true,
|
||||
minimumLicenseRequired: 'gold' as LicenseType,
|
||||
},
|
||||
];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.listTypes.mockResolvedValueOnce(listTypes);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: { id: '1' },
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
});
|
42
x-pack/plugins/actions/server/routes/connector_types.ts
Normal file
42
x-pack/plugins/actions/server/routes/connector_types.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { ActionType, BASE_ACTION_API_PATH } from '../../common';
|
||||
import { ActionsRequestHandlerContext } from '../types';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
import { RewriteResponseCase } from './rewrite_request_case';
|
||||
|
||||
const rewriteBodyRes: RewriteResponseCase<ActionType[]> = (results) => {
|
||||
return results.map(({ enabledInConfig, enabledInLicense, minimumLicenseRequired, ...res }) => ({
|
||||
...res,
|
||||
enabled_in_config: enabledInConfig,
|
||||
enabled_in_license: enabledInLicense,
|
||||
minimum_license_required: minimumLicenseRequired,
|
||||
}));
|
||||
};
|
||||
|
||||
export const connectorTypesRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.get(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/connector_types`,
|
||||
validate: {},
|
||||
},
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
return res.ok({
|
||||
body: rewriteBodyRes(await actionsClient.listTypes()),
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
|
@ -8,16 +8,18 @@
|
|||
import { createActionRoute } from './create';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { verifyApiAccess, ActionTypeDisabledError } from '../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { mockHandlerArguments } from './legacy/_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../actions_client.mock';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
jest.mock('../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
jest.mock('./verify_access_and_context.ts', () => ({
|
||||
verifyAccessAndContext: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation((license, handler) => handler);
|
||||
});
|
||||
|
||||
describe('createActionRoute', () => {
|
||||
|
@ -29,7 +31,7 @@ describe('createActionRoute', () => {
|
|||
|
||||
const [config, handler] = router.post.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action"`);
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connector"`);
|
||||
|
||||
const createResult = {
|
||||
id: '1',
|
||||
|
@ -39,6 +41,12 @@ describe('createActionRoute', () => {
|
|||
isPreconfigured: false,
|
||||
};
|
||||
|
||||
const createApiResult = {
|
||||
...omit(createResult, ['actionTypeId', 'isPreconfigured']),
|
||||
connector_type_id: createResult.actionTypeId,
|
||||
is_preconfigured: createResult.isPreconfigured,
|
||||
};
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.create.mockResolvedValueOnce(createResult);
|
||||
|
||||
|
@ -47,7 +55,7 @@ describe('createActionRoute', () => {
|
|||
{
|
||||
body: {
|
||||
name: 'My name',
|
||||
actionTypeId: 'abc',
|
||||
connector_type_id: 'abc',
|
||||
config: { foo: true },
|
||||
secrets: {},
|
||||
},
|
||||
|
@ -55,7 +63,7 @@ describe('createActionRoute', () => {
|
|||
['ok']
|
||||
);
|
||||
|
||||
expect(await handler(context, req, res)).toEqual({ body: createResult });
|
||||
expect(await handler(context, req, res)).toEqual({ body: createApiResult });
|
||||
|
||||
expect(actionsClient.create).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.create.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
|
@ -74,7 +82,7 @@ describe('createActionRoute', () => {
|
|||
`);
|
||||
|
||||
expect(res.ok).toHaveBeenCalledWith({
|
||||
body: createResult,
|
||||
body: createApiResult,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -95,18 +103,28 @@ describe('createActionRoute', () => {
|
|||
isPreconfigured: false,
|
||||
});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {});
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {
|
||||
name: 'My name',
|
||||
connector_type_id: 'abc',
|
||||
config: { foo: true },
|
||||
secrets: {},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
|
||||
it('ensures the license check prevents creating actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
|
@ -123,28 +141,18 @@ describe('createActionRoute', () => {
|
|||
isPreconfigured: false,
|
||||
});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {});
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {
|
||||
name: 'My name',
|
||||
connector_type_id: 'abc',
|
||||
config: { foo: true },
|
||||
secrets: {},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the action type gets validated for the license', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
createActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.create.mockRejectedValue(new ActionTypeDisabledError('Fail', 'license_invalid'));
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok', 'forbidden']);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(res.forbidden).toHaveBeenCalledWith({ body: { message: 'Fail' } });
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,46 +8,54 @@
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ActionResult, ActionsRequestHandlerContext } from '../types';
|
||||
import { ILicenseState, verifyApiAccess, isErrorThatHandlesItsOwnResponse } from '../lib';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../common';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
import { RewriteRequestCase, RewriteResponseCase } from './rewrite_request_case';
|
||||
import { CreateOptions } from '../actions_client';
|
||||
|
||||
export const bodySchema = schema.object({
|
||||
name: schema.string(),
|
||||
actionTypeId: schema.string(),
|
||||
connector_type_id: schema.string(),
|
||||
config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
|
||||
secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
|
||||
});
|
||||
|
||||
const rewriteBodyReq: RewriteRequestCase<CreateOptions['action']> = ({
|
||||
connector_type_id: actionTypeId,
|
||||
name,
|
||||
config,
|
||||
secrets,
|
||||
}) => ({ actionTypeId, name, config, secrets });
|
||||
const rewriteBodyRes: RewriteResponseCase<ActionResult> = ({
|
||||
actionTypeId,
|
||||
isPreconfigured,
|
||||
...res
|
||||
}) => ({
|
||||
...res,
|
||||
connector_type_id: actionTypeId,
|
||||
is_preconfigured: isPreconfigured,
|
||||
});
|
||||
|
||||
export const createActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.post(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action`,
|
||||
path: `${BASE_ACTION_API_PATH}/connector`,
|
||||
validate: {
|
||||
body: bodySchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const action = req.body;
|
||||
try {
|
||||
const actionRes: ActionResult = await actionsClient.create({ action });
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const action = rewriteBodyReq(req.body);
|
||||
return res.ok({
|
||||
body: actionRes,
|
||||
body: rewriteBodyRes(await actionsClient.create({ action })),
|
||||
});
|
||||
} catch (e) {
|
||||
if (isErrorThatHandlesItsOwnResponse(e)) {
|
||||
return e.sendResponse(res);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,16 +8,17 @@
|
|||
import { deleteActionRoute } from './delete';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { mockHandlerArguments } from './legacy/_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../mocks';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
|
||||
jest.mock('../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
jest.mock('./verify_access_and_context.ts', () => ({
|
||||
verifyAccessAndContext: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation((license, handler) => handler);
|
||||
});
|
||||
|
||||
describe('deleteActionRoute', () => {
|
||||
|
@ -29,7 +30,7 @@ describe('deleteActionRoute', () => {
|
|||
|
||||
const [config, handler] = router.delete.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action/{id}"`);
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connector/{id}"`);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.delete.mockResolvedValueOnce({});
|
||||
|
@ -78,14 +79,14 @@ describe('deleteActionRoute', () => {
|
|||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
|
||||
it('ensures the license check prevents deleting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
|
@ -105,6 +106,6 @@ describe('deleteActionRoute', () => {
|
|||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess, isErrorThatHandlesItsOwnResponse } from '../lib';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../common';
|
||||
import { ActionsRequestHandlerContext } from '../types';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
|
@ -21,27 +22,18 @@ export const deleteActionRoute = (
|
|||
) => {
|
||||
router.delete(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action/{id}`,
|
||||
path: `${BASE_ACTION_API_PATH}/connector/{id}`,
|
||||
validate: {
|
||||
params: paramSchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
try {
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
await actionsClient.delete({ id });
|
||||
return res.noContent();
|
||||
} catch (e) {
|
||||
if (isErrorThatHandlesItsOwnResponse(e)) {
|
||||
return e.sendResponse(res);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,17 +8,19 @@
|
|||
import { executeActionRoute } from './execute';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { verifyApiAccess, ActionTypeDisabledError, asHttpRequestExecutionSource } from '../lib';
|
||||
import { mockHandlerArguments } from './legacy/_mock_handler_arguments';
|
||||
import { asHttpRequestExecutionSource } from '../lib';
|
||||
import { actionsClientMock } from '../actions_client.mock';
|
||||
import { ActionTypeExecutorResult } from '../types';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
|
||||
jest.mock('../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
jest.mock('./verify_access_and_context.ts', () => ({
|
||||
verifyAccessAndContext: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation((license, handler) => handler);
|
||||
});
|
||||
|
||||
describe('executeActionRoute', () => {
|
||||
|
@ -45,7 +47,7 @@ describe('executeActionRoute', () => {
|
|||
);
|
||||
|
||||
const executeResult = {
|
||||
actionId: '1',
|
||||
connector_id: '1',
|
||||
status: 'ok',
|
||||
};
|
||||
|
||||
|
@ -53,7 +55,7 @@ describe('executeActionRoute', () => {
|
|||
|
||||
const [config, handler] = router.post.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action/{id}/_execute"`);
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connector/{id}/_execute"`);
|
||||
|
||||
expect(await handler(context, req, res)).toEqual({ body: executeResult });
|
||||
|
||||
|
@ -131,7 +133,7 @@ describe('executeActionRoute', () => {
|
|||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
|
||||
it('ensures the license check prevents action execution', async () => {
|
||||
|
@ -144,7 +146,7 @@ describe('executeActionRoute', () => {
|
|||
status: 'ok',
|
||||
});
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
|
@ -163,31 +165,6 @@ describe('executeActionRoute', () => {
|
|||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the action type gets validated for the license', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.execute.mockRejectedValue(new ActionTypeDisabledError('Fail', 'license_invalid'));
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {},
|
||||
params: {},
|
||||
},
|
||||
['ok', 'forbidden']
|
||||
);
|
||||
|
||||
executeActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(res.forbidden).toHaveBeenCalledWith({ body: { message: 'Fail' } });
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess, isErrorThatHandlesItsOwnResponse } from '../lib';
|
||||
import { ILicenseState } from '../lib';
|
||||
|
||||
import { ActionTypeExecutorResult, ActionsRequestHandlerContext } from '../types';
|
||||
import { BASE_ACTION_API_PATH } from '../../common';
|
||||
import { asHttpRequestExecutionSource } from '../lib/action_execution_source';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
import { RewriteResponseCase } from './rewrite_request_case';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
|
@ -21,29 +23,33 @@ const bodySchema = schema.object({
|
|||
params: schema.recordOf(schema.string(), schema.any()),
|
||||
});
|
||||
|
||||
const rewriteBodyRes: RewriteResponseCase<ActionTypeExecutorResult<unknown>> = ({
|
||||
actionId,
|
||||
serviceMessage,
|
||||
...res
|
||||
}) => ({
|
||||
...res,
|
||||
connector_id: actionId,
|
||||
...(serviceMessage ? { service_message: serviceMessage } : {}),
|
||||
});
|
||||
|
||||
export const executeActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.post(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action/{id}/_execute`,
|
||||
path: `${BASE_ACTION_API_PATH}/connector/{id}/_execute`,
|
||||
validate: {
|
||||
body: bodySchema,
|
||||
params: paramSchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { params } = req.body;
|
||||
const { id } = req.params;
|
||||
try {
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { params } = req.body;
|
||||
const { id } = req.params;
|
||||
const body: ActionTypeExecutorResult<unknown> = await actionsClient.execute({
|
||||
params,
|
||||
actionId: id,
|
||||
|
@ -51,15 +57,10 @@ export const executeActionRoute = (
|
|||
});
|
||||
return body
|
||||
? res.ok({
|
||||
body,
|
||||
body: rewriteBodyRes(body),
|
||||
})
|
||||
: res.noContent();
|
||||
} catch (e) {
|
||||
if (isErrorThatHandlesItsOwnResponse(e)) {
|
||||
return e.sendResponse(res);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,16 +8,17 @@
|
|||
import { getActionRoute } from './get';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { mockHandlerArguments } from './legacy/_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../actions_client.mock';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
|
||||
jest.mock('../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
jest.mock('./verify_access_and_context.ts', () => ({
|
||||
verifyAccessAndContext: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation((license, handler) => handler);
|
||||
});
|
||||
|
||||
describe('getActionRoute', () => {
|
||||
|
@ -29,7 +30,7 @@ describe('getActionRoute', () => {
|
|||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action/{id}"`);
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connector/{id}"`);
|
||||
|
||||
const getResult = {
|
||||
id: '1',
|
||||
|
@ -53,10 +54,10 @@ describe('getActionRoute', () => {
|
|||
expect(await handler(context, req, res)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"body": Object {
|
||||
"actionTypeId": "2",
|
||||
"config": Object {},
|
||||
"connector_type_id": "2",
|
||||
"id": "1",
|
||||
"isPreconfigured": false,
|
||||
"is_preconfigured": false,
|
||||
"name": "action name",
|
||||
},
|
||||
}
|
||||
|
@ -66,7 +67,13 @@ describe('getActionRoute', () => {
|
|||
expect(actionsClient.get.mock.calls[0][0].id).toEqual('1');
|
||||
|
||||
expect(res.ok).toHaveBeenCalledWith({
|
||||
body: getResult,
|
||||
body: {
|
||||
id: '1',
|
||||
connector_type_id: '2',
|
||||
name: 'action name',
|
||||
config: {},
|
||||
is_preconfigured: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -97,14 +104,14 @@ describe('getActionRoute', () => {
|
|||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
|
||||
it('ensures the license check prevents getting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
|
@ -131,6 +138,6 @@ describe('getActionRoute', () => {
|
|||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,35 +7,45 @@
|
|||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess } from '../lib';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../common';
|
||||
import { ActionsRequestHandlerContext } from '../types';
|
||||
import { ActionResult, ActionsRequestHandlerContext } from '../types';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
import { RewriteResponseCase } from './rewrite_request_case';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
||||
|
||||
const rewriteBodyRes: RewriteResponseCase<ActionResult> = ({
|
||||
actionTypeId,
|
||||
isPreconfigured,
|
||||
...res
|
||||
}) => ({
|
||||
...res,
|
||||
connector_type_id: actionTypeId,
|
||||
is_preconfigured: isPreconfigured,
|
||||
});
|
||||
|
||||
export const getActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.get(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action/{id}`,
|
||||
path: `${BASE_ACTION_API_PATH}/connector/{id}`,
|
||||
validate: {
|
||||
params: paramSchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
return res.ok({
|
||||
body: await actionsClient.get({ id }),
|
||||
});
|
||||
})
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
return res.ok({
|
||||
body: rewriteBodyRes(await actionsClient.get({ id })),
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,16 +8,17 @@
|
|||
import { getAllActionRoute } from './get_all';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { mockHandlerArguments } from './legacy/_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../actions_client.mock';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
|
||||
jest.mock('../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
jest.mock('./verify_access_and_context.ts', () => ({
|
||||
verifyAccessAndContext: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation((license, handler) => handler);
|
||||
});
|
||||
|
||||
describe('getAllActionRoute', () => {
|
||||
|
@ -29,7 +30,7 @@ describe('getAllActionRoute', () => {
|
|||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions"`);
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connectors"`);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.getAll.mockResolvedValueOnce([]);
|
||||
|
@ -57,7 +58,7 @@ describe('getAllActionRoute', () => {
|
|||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions"`);
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connectors"`);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.getAll.mockResolvedValueOnce([]);
|
||||
|
@ -66,14 +67,14 @@ describe('getAllActionRoute', () => {
|
|||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
|
||||
it('ensures the license check prevents getting all actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
|
@ -81,7 +82,7 @@ describe('getAllActionRoute', () => {
|
|||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions"`);
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connectors"`);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.getAll.mockResolvedValueOnce([]);
|
||||
|
@ -90,6 +91,6 @@ describe('getAllActionRoute', () => {
|
|||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,9 +6,20 @@
|
|||
*/
|
||||
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess } from '../lib';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../common';
|
||||
import { ActionsRequestHandlerContext } from '../types';
|
||||
import { ActionsRequestHandlerContext, FindActionResult } from '../types';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
import { RewriteResponseCase } from './rewrite_request_case';
|
||||
|
||||
const rewriteBodyRes: RewriteResponseCase<FindActionResult[]> = (results) => {
|
||||
return results.map(({ actionTypeId, isPreconfigured, referencedByCount, ...res }) => ({
|
||||
...res,
|
||||
connector_type_id: actionTypeId,
|
||||
is_preconfigured: isPreconfigured,
|
||||
referenced_by_count: referencedByCount,
|
||||
}));
|
||||
};
|
||||
|
||||
export const getAllActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
|
@ -16,19 +27,17 @@ export const getAllActionRoute = (
|
|||
) => {
|
||||
router.get(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}`,
|
||||
path: `${BASE_ACTION_API_PATH}/connectors`,
|
||||
validate: {},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const result = await actionsClient.getAll();
|
||||
return res.ok({
|
||||
body: result,
|
||||
});
|
||||
})
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const result = await actionsClient.getAll();
|
||||
return res.ok({
|
||||
body: rewriteBodyRes(result),
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -5,10 +5,29 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export { createActionRoute } from './create';
|
||||
export { deleteActionRoute } from './delete';
|
||||
export { getAllActionRoute } from './get_all';
|
||||
export { getActionRoute } from './get';
|
||||
export { updateActionRoute } from './update';
|
||||
export { listActionTypesRoute } from './list_action_types';
|
||||
export { executeActionRoute } from './execute';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { ActionsRequestHandlerContext } from '../types';
|
||||
import { createActionRoute } from './create';
|
||||
import { deleteActionRoute } from './delete';
|
||||
import { executeActionRoute } from './execute';
|
||||
import { getActionRoute } from './get';
|
||||
import { getAllActionRoute } from './get_all';
|
||||
import { connectorTypesRoute } from './connector_types';
|
||||
import { updateActionRoute } from './update';
|
||||
import { defineLegacyRoutes } from './legacy';
|
||||
|
||||
export function defineRoutes(
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) {
|
||||
defineLegacyRoutes(router, licenseState);
|
||||
|
||||
createActionRoute(router, licenseState);
|
||||
deleteActionRoute(router, licenseState);
|
||||
getActionRoute(router, licenseState);
|
||||
getAllActionRoute(router, licenseState);
|
||||
updateActionRoute(router, licenseState);
|
||||
connectorTypesRoute(router, licenseState);
|
||||
executeActionRoute(router, licenseState);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { RequestHandlerContext, KibanaRequest, KibanaResponseFactory } from 'kibana/server';
|
||||
import { KibanaRequest, KibanaResponseFactory } from 'kibana/server';
|
||||
import { identity } from 'lodash';
|
||||
import type { MethodKeysOf } from '@kbn/utility-types';
|
||||
import { httpServerMock } from '../../../../../src/core/server/mocks';
|
||||
import { ActionType } from '../../common';
|
||||
import { ActionsClientMock, actionsClientMock } from '../actions_client.mock';
|
||||
import { httpServerMock } from '../../../../../../src/core/server/mocks';
|
||||
import { ActionType } from '../../../common';
|
||||
import { ActionsClientMock, actionsClientMock } from '../../actions_client.mock';
|
||||
import { ActionsRequestHandlerContext } from '../../types';
|
||||
|
||||
export function mockHandlerArguments(
|
||||
{
|
||||
|
@ -19,7 +20,7 @@ export function mockHandlerArguments(
|
|||
}: { actionsClient?: ActionsClientMock; listTypes?: ActionType[] },
|
||||
req: unknown,
|
||||
res?: Array<MethodKeysOf<KibanaResponseFactory>>
|
||||
): [RequestHandlerContext, KibanaRequest<unknown, unknown, unknown>, KibanaResponseFactory] {
|
||||
): [ActionsRequestHandlerContext, KibanaRequest<unknown, unknown, unknown>, KibanaResponseFactory] {
|
||||
const listTypes = jest.fn(() => listTypesRes);
|
||||
return [
|
||||
({
|
||||
|
@ -37,7 +38,7 @@ export function mockHandlerArguments(
|
|||
);
|
||||
},
|
||||
},
|
||||
} as unknown) as RequestHandlerContext,
|
||||
} as unknown) as ActionsRequestHandlerContext,
|
||||
req as KibanaRequest<unknown, unknown, unknown>,
|
||||
mockResponseFactory(res),
|
||||
];
|
131
x-pack/plugins/actions/server/routes/legacy/create.test.ts
Normal file
131
x-pack/plugins/actions/server/routes/legacy/create.test.ts
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { createActionRoute } from './create';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../../lib/license_state.mock';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../../actions_client.mock';
|
||||
import { verifyAccessAndContext } from '../verify_access_and_context';
|
||||
|
||||
jest.mock('../verify_access_and_context.ts', () => ({
|
||||
verifyAccessAndContext: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation((license, handler) => handler);
|
||||
});
|
||||
|
||||
describe('createActionRoute', () => {
|
||||
it('creates an action with proper parameters', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
createActionRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.post.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action"`);
|
||||
|
||||
const createResult = {
|
||||
id: '1',
|
||||
name: 'My name',
|
||||
actionTypeId: 'abc',
|
||||
config: { foo: true },
|
||||
isPreconfigured: false,
|
||||
};
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.create.mockResolvedValueOnce(createResult);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {
|
||||
name: 'My name',
|
||||
actionTypeId: 'abc',
|
||||
config: { foo: true },
|
||||
secrets: {},
|
||||
},
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
expect(await handler(context, req, res)).toEqual({ body: createResult });
|
||||
|
||||
expect(actionsClient.create).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.create.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"action": Object {
|
||||
"actionTypeId": "abc",
|
||||
"config": Object {
|
||||
"foo": true,
|
||||
},
|
||||
"name": "My name",
|
||||
"secrets": Object {},
|
||||
},
|
||||
},
|
||||
]
|
||||
`);
|
||||
|
||||
expect(res.ok).toHaveBeenCalledWith({
|
||||
body: createResult,
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures the license allows creating actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
createActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.create.mockResolvedValueOnce({
|
||||
id: '1',
|
||||
name: 'My name',
|
||||
actionTypeId: 'abc',
|
||||
config: { foo: true },
|
||||
isPreconfigured: false,
|
||||
});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {});
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
|
||||
it('ensures the license check prevents creating actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
createActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.create.mockResolvedValueOnce({
|
||||
id: '1',
|
||||
name: 'My name',
|
||||
actionTypeId: 'abc',
|
||||
config: { foo: true },
|
||||
isPreconfigured: false,
|
||||
});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {});
|
||||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
});
|
||||
});
|
43
x-pack/plugins/actions/server/routes/legacy/create.ts
Normal file
43
x-pack/plugins/actions/server/routes/legacy/create.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ActionsRequestHandlerContext } from '../../types';
|
||||
import { ILicenseState } from '../../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../../common';
|
||||
import { verifyAccessAndContext } from '../verify_access_and_context';
|
||||
|
||||
export const bodySchema = schema.object({
|
||||
name: schema.string(),
|
||||
actionTypeId: schema.string(),
|
||||
config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
|
||||
secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
|
||||
});
|
||||
|
||||
export const createActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.post(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action`,
|
||||
validate: {
|
||||
body: bodySchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const action = req.body;
|
||||
return res.ok({
|
||||
body: await actionsClient.create({ action }),
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
110
x-pack/plugins/actions/server/routes/legacy/delete.test.ts
Normal file
110
x-pack/plugins/actions/server/routes/legacy/delete.test.ts
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { deleteActionRoute } from './delete';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../../mocks';
|
||||
|
||||
jest.mock('../../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('deleteActionRoute', () => {
|
||||
it('deletes an action with proper parameters', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
deleteActionRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.delete.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action/{id}"`);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.delete.mockResolvedValueOnce({});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: {
|
||||
id: '1',
|
||||
},
|
||||
},
|
||||
['noContent']
|
||||
);
|
||||
|
||||
expect(await handler(context, req, res)).toEqual(undefined);
|
||||
|
||||
expect(actionsClient.delete).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.delete.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
},
|
||||
]
|
||||
`);
|
||||
|
||||
expect(res.noContent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('ensures the license allows deleting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
deleteActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.delete.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.delete.mockResolvedValueOnce({});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: { id: '1' },
|
||||
}
|
||||
);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the license check prevents deleting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
deleteActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.delete.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.delete.mockResolvedValueOnce({});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
id: '1',
|
||||
}
|
||||
);
|
||||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
});
|
47
x-pack/plugins/actions/server/routes/legacy/delete.ts
Normal file
47
x-pack/plugins/actions/server/routes/legacy/delete.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess, isErrorThatHandlesItsOwnResponse } from '../../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../../common';
|
||||
import { ActionsRequestHandlerContext } from '../../types';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
||||
|
||||
export const deleteActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.delete(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action/{id}`,
|
||||
validate: {
|
||||
params: paramSchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
try {
|
||||
await actionsClient.delete({ id });
|
||||
return res.noContent();
|
||||
} catch (e) {
|
||||
if (isErrorThatHandlesItsOwnResponse(e)) {
|
||||
return e.sendResponse(res);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
193
x-pack/plugins/actions/server/routes/legacy/execute.test.ts
Normal file
193
x-pack/plugins/actions/server/routes/legacy/execute.test.ts
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { executeActionRoute } from './execute';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../../lib/license_state.mock';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { verifyApiAccess, ActionTypeDisabledError, asHttpRequestExecutionSource } from '../../lib';
|
||||
import { actionsClientMock } from '../../actions_client.mock';
|
||||
import { ActionTypeExecutorResult } from '../../types';
|
||||
|
||||
jest.mock('../../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('executeActionRoute', () => {
|
||||
it('executes an action with proper parameters', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.execute.mockResolvedValueOnce({ status: 'ok', actionId: '1' });
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {
|
||||
params: {
|
||||
someData: 'data',
|
||||
},
|
||||
},
|
||||
params: {
|
||||
id: '1',
|
||||
},
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
const executeResult = {
|
||||
actionId: '1',
|
||||
status: 'ok',
|
||||
};
|
||||
|
||||
executeActionRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.post.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action/{id}/_execute"`);
|
||||
|
||||
expect(await handler(context, req, res)).toEqual({ body: executeResult });
|
||||
|
||||
expect(actionsClient.execute).toHaveBeenCalledWith({
|
||||
actionId: '1',
|
||||
params: {
|
||||
someData: 'data',
|
||||
},
|
||||
source: asHttpRequestExecutionSource(req),
|
||||
});
|
||||
|
||||
expect(res.ok).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns a "204 NO CONTENT" when the executor returns a nullish value', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.execute.mockResolvedValueOnce(
|
||||
(null as unknown) as ActionTypeExecutorResult<void>
|
||||
);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {
|
||||
params: {},
|
||||
},
|
||||
params: {
|
||||
id: '1',
|
||||
},
|
||||
},
|
||||
['noContent']
|
||||
);
|
||||
|
||||
executeActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
expect(await handler(context, req, res)).toEqual(undefined);
|
||||
|
||||
expect(actionsClient.execute).toHaveBeenCalledWith({
|
||||
actionId: '1',
|
||||
params: {},
|
||||
source: asHttpRequestExecutionSource(req),
|
||||
});
|
||||
|
||||
expect(res.ok).not.toHaveBeenCalled();
|
||||
expect(res.noContent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('ensures the license allows action execution', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.execute.mockResolvedValue({
|
||||
actionId: '1',
|
||||
status: 'ok',
|
||||
});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {},
|
||||
params: {},
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
executeActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the license check prevents action execution', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.execute.mockResolvedValue({
|
||||
actionId: '1',
|
||||
status: 'ok',
|
||||
});
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {},
|
||||
params: {},
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
executeActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the action type gets validated for the license', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.execute.mockRejectedValue(new ActionTypeDisabledError('Fail', 'license_invalid'));
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
body: {},
|
||||
params: {},
|
||||
},
|
||||
['ok', 'forbidden']
|
||||
);
|
||||
|
||||
executeActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(res.forbidden).toHaveBeenCalledWith({ body: { message: 'Fail' } });
|
||||
});
|
||||
});
|
65
x-pack/plugins/actions/server/routes/legacy/execute.ts
Normal file
65
x-pack/plugins/actions/server/routes/legacy/execute.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess, isErrorThatHandlesItsOwnResponse } from '../../lib';
|
||||
|
||||
import { ActionTypeExecutorResult, ActionsRequestHandlerContext } from '../../types';
|
||||
import { BASE_ACTION_API_PATH } from '../../../common';
|
||||
import { asHttpRequestExecutionSource } from '../../lib/action_execution_source';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
||||
|
||||
const bodySchema = schema.object({
|
||||
params: schema.recordOf(schema.string(), schema.any()),
|
||||
});
|
||||
|
||||
export const executeActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.post(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action/{id}/_execute`,
|
||||
validate: {
|
||||
body: bodySchema,
|
||||
params: paramSchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { params } = req.body;
|
||||
const { id } = req.params;
|
||||
try {
|
||||
const body: ActionTypeExecutorResult<unknown> = await actionsClient.execute({
|
||||
params,
|
||||
actionId: id,
|
||||
source: asHttpRequestExecutionSource(req),
|
||||
});
|
||||
return body
|
||||
? res.ok({
|
||||
body,
|
||||
})
|
||||
: res.noContent();
|
||||
} catch (e) {
|
||||
if (isErrorThatHandlesItsOwnResponse(e)) {
|
||||
return e.sendResponse(res);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
136
x-pack/plugins/actions/server/routes/legacy/get.test.ts
Normal file
136
x-pack/plugins/actions/server/routes/legacy/get.test.ts
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getActionRoute } from './get';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../../actions_client.mock';
|
||||
|
||||
jest.mock('../../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('getActionRoute', () => {
|
||||
it('gets an action with proper parameters', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
getActionRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action/{id}"`);
|
||||
|
||||
const getResult = {
|
||||
id: '1',
|
||||
actionTypeId: '2',
|
||||
name: 'action name',
|
||||
config: {},
|
||||
isPreconfigured: false,
|
||||
};
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.get.mockResolvedValueOnce(getResult);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: { id: '1' },
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
expect(await handler(context, req, res)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"body": Object {
|
||||
"actionTypeId": "2",
|
||||
"config": Object {},
|
||||
"id": "1",
|
||||
"isPreconfigured": false,
|
||||
"name": "action name",
|
||||
},
|
||||
}
|
||||
`);
|
||||
|
||||
expect(actionsClient.get).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.get.mock.calls[0][0].id).toEqual('1');
|
||||
|
||||
expect(res.ok).toHaveBeenCalledWith({
|
||||
body: getResult,
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures the license allows getting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
getActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.get.mockResolvedValueOnce({
|
||||
id: '1',
|
||||
actionTypeId: '2',
|
||||
name: 'action name',
|
||||
config: {},
|
||||
isPreconfigured: false,
|
||||
});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: { id: '1' },
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the license check prevents getting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
getActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.get.mockResolvedValueOnce({
|
||||
id: '1',
|
||||
actionTypeId: '2',
|
||||
name: 'action name',
|
||||
config: {},
|
||||
isPreconfigured: false,
|
||||
});
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: { id: '1' },
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
});
|
41
x-pack/plugins/actions/server/routes/legacy/get.ts
Normal file
41
x-pack/plugins/actions/server/routes/legacy/get.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess } from '../../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../../common';
|
||||
import { ActionsRequestHandlerContext } from '../../types';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
||||
|
||||
export const getActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.get(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action/{id}`,
|
||||
validate: {
|
||||
params: paramSchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
return res.ok({
|
||||
body: await actionsClient.get({ id }),
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
95
x-pack/plugins/actions/server/routes/legacy/get_all.test.ts
Normal file
95
x-pack/plugins/actions/server/routes/legacy/get_all.test.ts
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getAllActionRoute } from './get_all';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../../actions_client.mock';
|
||||
|
||||
jest.mock('../../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('getAllActionRoute', () => {
|
||||
it('get all actions with proper parameters', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
getAllActionRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions"`);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.getAll.mockResolvedValueOnce([]);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']);
|
||||
|
||||
expect(await handler(context, req, res)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"body": Array [],
|
||||
}
|
||||
`);
|
||||
|
||||
expect(actionsClient.getAll).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(res.ok).toHaveBeenCalledWith({
|
||||
body: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures the license allows getting all actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
getAllActionRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions"`);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.getAll.mockResolvedValueOnce([]);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the license check prevents getting all actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
getAllActionRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions"`);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.getAll.mockResolvedValueOnce([]);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']);
|
||||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
});
|
34
x-pack/plugins/actions/server/routes/legacy/get_all.ts
Normal file
34
x-pack/plugins/actions/server/routes/legacy/get_all.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess } from '../../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../../common';
|
||||
import { ActionsRequestHandlerContext } from '../../types';
|
||||
|
||||
export const getAllActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.get(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}`,
|
||||
validate: {},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const result = await actionsClient.getAll();
|
||||
return res.ok({
|
||||
body: result,
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
30
x-pack/plugins/actions/server/routes/legacy/index.ts
Normal file
30
x-pack/plugins/actions/server/routes/legacy/index.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState } from '../../lib';
|
||||
import { ActionsRequestHandlerContext } from '../../types';
|
||||
import { createActionRoute } from './create';
|
||||
import { deleteActionRoute } from './delete';
|
||||
import { getAllActionRoute } from './get_all';
|
||||
import { getActionRoute } from './get';
|
||||
import { updateActionRoute } from './update';
|
||||
import { listActionTypesRoute } from './list_action_types';
|
||||
import { executeActionRoute } from './execute';
|
||||
|
||||
export function defineLegacyRoutes(
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) {
|
||||
createActionRoute(router, licenseState);
|
||||
deleteActionRoute(router, licenseState);
|
||||
getActionRoute(router, licenseState);
|
||||
getAllActionRoute(router, licenseState);
|
||||
updateActionRoute(router, licenseState);
|
||||
listActionTypesRoute(router, licenseState);
|
||||
executeActionRoute(router, licenseState);
|
||||
}
|
|
@ -7,13 +7,13 @@
|
|||
|
||||
import { listActionTypesRoute } from './list_action_types';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../lib';
|
||||
import { licenseStateMock } from '../../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { LicenseType } from '../../../../plugins/licensing/server';
|
||||
import { actionsClientMock } from '../mocks';
|
||||
import { LicenseType } from '../../../../../plugins/licensing/server';
|
||||
import { actionsClientMock } from '../../mocks';
|
||||
|
||||
jest.mock('../lib/verify_api_access.ts', () => ({
|
||||
jest.mock('../../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess } from '../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../common';
|
||||
import { ActionsRequestHandlerContext } from '../types';
|
||||
import { ILicenseState, verifyApiAccess } from '../../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../../common';
|
||||
import { ActionsRequestHandlerContext } from '../../types';
|
||||
|
||||
export const listActionTypesRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
185
x-pack/plugins/actions/server/routes/legacy/update.test.ts
Normal file
185
x-pack/plugins/actions/server/routes/legacy/update.test.ts
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { updateActionRoute } from './update';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../../lib/license_state.mock';
|
||||
import { verifyApiAccess, ActionTypeDisabledError } from '../../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../../actions_client.mock';
|
||||
|
||||
jest.mock('../../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('updateActionRoute', () => {
|
||||
it('updates an action with proper parameters', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
updateActionRoute(router, licenseState);
|
||||
|
||||
const [config, handler] = router.put.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action/{id}"`);
|
||||
|
||||
const updateResult = {
|
||||
id: '1',
|
||||
actionTypeId: 'my-action-type-id',
|
||||
name: 'My name',
|
||||
config: { foo: true },
|
||||
isPreconfigured: false,
|
||||
};
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.update.mockResolvedValueOnce(updateResult);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: {
|
||||
id: '1',
|
||||
},
|
||||
body: {
|
||||
name: 'My name',
|
||||
config: { foo: true },
|
||||
secrets: { key: 'i8oh34yf9783y39' },
|
||||
},
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
expect(await handler(context, req, res)).toEqual({ body: updateResult });
|
||||
|
||||
expect(actionsClient.update).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.update.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"action": Object {
|
||||
"config": Object {
|
||||
"foo": true,
|
||||
},
|
||||
"name": "My name",
|
||||
"secrets": Object {
|
||||
"key": "i8oh34yf9783y39",
|
||||
},
|
||||
},
|
||||
"id": "1",
|
||||
},
|
||||
]
|
||||
`);
|
||||
|
||||
expect(res.ok).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('ensures the license allows deleting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
updateActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.put.mock.calls[0];
|
||||
|
||||
const updateResult = {
|
||||
id: '1',
|
||||
actionTypeId: 'my-action-type-id',
|
||||
name: 'My name',
|
||||
config: { foo: true },
|
||||
isPreconfigured: false,
|
||||
};
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.update.mockResolvedValueOnce(updateResult);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: {
|
||||
id: '1',
|
||||
},
|
||||
body: {
|
||||
name: 'My name',
|
||||
config: { foo: true },
|
||||
secrets: { key: 'i8oh34yf9783y39' },
|
||||
},
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the license check prevents deleting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
updateActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.put.mock.calls[0];
|
||||
|
||||
const updateResult = {
|
||||
id: '1',
|
||||
actionTypeId: 'my-action-type-id',
|
||||
name: 'My name',
|
||||
config: { foo: true },
|
||||
isPreconfigured: false,
|
||||
};
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.update.mockResolvedValueOnce(updateResult);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ actionsClient },
|
||||
{
|
||||
params: {
|
||||
id: '1',
|
||||
},
|
||||
body: {
|
||||
name: 'My name',
|
||||
config: { foo: true },
|
||||
secrets: { key: 'i8oh34yf9783y39' },
|
||||
},
|
||||
},
|
||||
['ok']
|
||||
);
|
||||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the action type gets validated for the license', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
updateActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.put.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.update.mockRejectedValue(new ActionTypeDisabledError('Fail', 'license_invalid'));
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, { params: {}, body: {} }, [
|
||||
'ok',
|
||||
'forbidden',
|
||||
]);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(res.forbidden).toHaveBeenCalledWith({ body: { message: 'Fail' } });
|
||||
});
|
||||
});
|
60
x-pack/plugins/actions/server/routes/legacy/update.ts
Normal file
60
x-pack/plugins/actions/server/routes/legacy/update.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess, isErrorThatHandlesItsOwnResponse } from '../../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../../common';
|
||||
import { ActionsRequestHandlerContext } from '../../types';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
||||
|
||||
const bodySchema = schema.object({
|
||||
name: schema.string(),
|
||||
config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
|
||||
secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
|
||||
});
|
||||
|
||||
export const updateActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.put(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action/{id}`,
|
||||
validate: {
|
||||
body: bodySchema,
|
||||
params: paramSchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
const { name, config, secrets } = req.body;
|
||||
|
||||
try {
|
||||
return res.ok({
|
||||
body: await actionsClient.update({
|
||||
id,
|
||||
action: { name, config, secrets },
|
||||
}),
|
||||
});
|
||||
} catch (e) {
|
||||
if (isErrorThatHandlesItsOwnResponse(e)) {
|
||||
return e.sendResponse(res);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
48
x-pack/plugins/actions/server/routes/rewrite_request_case.ts
Normal file
48
x-pack/plugins/actions/server/routes/rewrite_request_case.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
type RenameActionToConnector<K extends string> = K extends `actionTypeId`
|
||||
? `connectorTypeId`
|
||||
: K extends `actionId`
|
||||
? `connectorId`
|
||||
: K;
|
||||
|
||||
export type AsApiContract<T> = {
|
||||
[K in keyof T as CamelToSnake<RenameActionToConnector<Extract<K, string>>>]: T[K];
|
||||
};
|
||||
|
||||
export type RewriteRequestCase<T> = (requested: AsApiContract<T>) => T;
|
||||
export type RewriteResponseCase<T> = (
|
||||
responded: T
|
||||
) => T extends Array<infer Item> ? Array<AsApiContract<Item>> : AsApiContract<T>;
|
||||
|
||||
/**
|
||||
* This type maps Camel Case strings into their Snake Case version.
|
||||
* This is achieved by checking each character and, if it is an uppercase character, it is mapped to an
|
||||
* underscore followed by a lowercase one.
|
||||
*
|
||||
* The reason there are two ternaries is that, for perfformance reasons, TS limits its
|
||||
* character parsing to ~15 characters.
|
||||
* To get around this we use the second turnery to parse 2 characters at a time, which allows us to support
|
||||
* strings that are 30 characters long.
|
||||
*
|
||||
* If you get the TS #2589 error ("Type instantiation is excessively deep and possibly infinite") then most
|
||||
* likely you have a string that's longer than 30 characters.
|
||||
* Address this by reducing the length if possible, otherwise, you'll need to add a 3rd ternary which
|
||||
* parses 3 chars at a time :grimace:
|
||||
*
|
||||
* For more details see this PR comment: https://github.com/microsoft/TypeScript/pull/40336#issuecomment-686723087
|
||||
*/
|
||||
type CamelToSnake<T extends string> = string extends T
|
||||
? string
|
||||
: T extends `${infer C0}${infer C1}${infer R}`
|
||||
? `${C0 extends Uppercase<C0> ? '_' : ''}${Lowercase<C0>}${C1 extends Uppercase<C1>
|
||||
? '_'
|
||||
: ''}${Lowercase<C1>}${CamelToSnake<R>}`
|
||||
: T extends `${infer C0}${infer R}`
|
||||
? `${C0 extends Uppercase<C0> ? '_' : ''}${Lowercase<C0>}${CamelToSnake<R>}`
|
||||
: '';
|
|
@ -8,16 +8,17 @@
|
|||
import { updateActionRoute } from './update';
|
||||
import { httpServiceMock } from 'src/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { verifyApiAccess, ActionTypeDisabledError } from '../lib';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { mockHandlerArguments } from './legacy/_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../actions_client.mock';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
|
||||
jest.mock('../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
jest.mock('./verify_access_and_context.ts', () => ({
|
||||
verifyAccessAndContext: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation((license, handler) => handler);
|
||||
});
|
||||
|
||||
describe('updateActionRoute', () => {
|
||||
|
@ -29,7 +30,7 @@ describe('updateActionRoute', () => {
|
|||
|
||||
const [config, handler] = router.put.mock.calls[0];
|
||||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/action/{id}"`);
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/actions/connector/{id}"`);
|
||||
|
||||
const updateResult = {
|
||||
id: '1',
|
||||
|
@ -57,7 +58,15 @@ describe('updateActionRoute', () => {
|
|||
['ok']
|
||||
);
|
||||
|
||||
expect(await handler(context, req, res)).toEqual({ body: updateResult });
|
||||
expect(await handler(context, req, res)).toEqual({
|
||||
body: {
|
||||
id: '1',
|
||||
connector_type_id: 'my-action-type-id',
|
||||
name: 'My name',
|
||||
config: { foo: true },
|
||||
is_preconfigured: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(actionsClient.update).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.update.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
|
@ -116,14 +125,14 @@ describe('updateActionRoute', () => {
|
|||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
|
||||
it('ensures the license check prevents deleting actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
(verifyAccessAndContext as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
|
@ -159,27 +168,6 @@ describe('updateActionRoute', () => {
|
|||
|
||||
expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the action type gets validated for the license', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
updateActionRoute(router, licenseState);
|
||||
|
||||
const [, handler] = router.put.mock.calls[0];
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
actionsClient.update.mockRejectedValue(new ActionTypeDisabledError('Fail', 'license_invalid'));
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, { params: {}, body: {} }, [
|
||||
'ok',
|
||||
'forbidden',
|
||||
]);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(res.forbidden).toHaveBeenCalledWith({ body: { message: 'Fail' } });
|
||||
expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from 'kibana/server';
|
||||
import { ILicenseState, verifyApiAccess, isErrorThatHandlesItsOwnResponse } from '../lib';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { BASE_ACTION_API_PATH } from '../../common';
|
||||
import { ActionsRequestHandlerContext } from '../types';
|
||||
import { ActionResult, ActionsRequestHandlerContext } from '../types';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
import { RewriteResponseCase } from './rewrite_request_case';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
|
@ -21,40 +23,43 @@ const bodySchema = schema.object({
|
|||
secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
|
||||
});
|
||||
|
||||
const rewriteBodyRes: RewriteResponseCase<ActionResult> = ({
|
||||
actionTypeId,
|
||||
isPreconfigured,
|
||||
...res
|
||||
}) => ({
|
||||
...res,
|
||||
connector_type_id: actionTypeId,
|
||||
is_preconfigured: isPreconfigured,
|
||||
});
|
||||
|
||||
export const updateActionRoute = (
|
||||
router: IRouter<ActionsRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.put(
|
||||
{
|
||||
path: `${BASE_ACTION_API_PATH}/action/{id}`,
|
||||
path: `${BASE_ACTION_API_PATH}/connector/{id}`,
|
||||
validate: {
|
||||
body: bodySchema,
|
||||
params: paramSchema,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(async function (context, req, res) {
|
||||
verifyApiAccess(licenseState);
|
||||
if (!context.actions) {
|
||||
return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
const { name, config, secrets } = req.body;
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const actionsClient = context.actions.getActionsClient();
|
||||
const { id } = req.params;
|
||||
const { name, config, secrets } = req.body;
|
||||
|
||||
try {
|
||||
return res.ok({
|
||||
body: await actionsClient.update({
|
||||
id,
|
||||
action: { name, config, secrets },
|
||||
}),
|
||||
body: rewriteBodyRes(
|
||||
await actionsClient.update({
|
||||
id,
|
||||
action: { name, config, secrets },
|
||||
})
|
||||
),
|
||||
});
|
||||
} catch (e) {
|
||||
if (isErrorThatHandlesItsOwnResponse(e)) {
|
||||
return e.sendResponse(res);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { verifyApiAccess, ActionTypeDisabledError } from '../lib';
|
||||
import { mockHandlerArguments } from './legacy/_mock_handler_arguments';
|
||||
import { actionsClientMock } from '../actions_client.mock';
|
||||
import { verifyAccessAndContext } from './verify_access_and_context';
|
||||
|
||||
jest.mock('../lib/verify_api_access.ts', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('verifyAccessAndContext', () => {
|
||||
it('ensures the license allows creating actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
|
||||
const handler = jest.fn();
|
||||
const verify = verifyAccessAndContext(licenseState, handler);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {});
|
||||
|
||||
await verify(context, req, res);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('ensures the license check prevents creating actions', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
|
||||
(verifyApiAccess as jest.Mock).mockImplementation(() => {
|
||||
throw new Error('OMG');
|
||||
});
|
||||
|
||||
const handler = jest.fn();
|
||||
const verify = verifyAccessAndContext(licenseState, handler);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {});
|
||||
|
||||
await expect(verify(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`);
|
||||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
});
|
||||
|
||||
it('supports error that handle their own response', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
|
||||
const handler = jest.fn();
|
||||
const verify = verifyAccessAndContext(licenseState, handler);
|
||||
|
||||
const actionsClient = actionsClientMock.create();
|
||||
const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok', 'forbidden']);
|
||||
|
||||
handler.mockRejectedValue(new ActionTypeDisabledError('Fail', 'license_invalid'));
|
||||
|
||||
await expect(verify(context, req, res)).resolves.toMatchObject({ body: { message: 'Fail' } });
|
||||
expect(res.forbidden).toHaveBeenCalledWith({ body: { message: 'Fail' } });
|
||||
});
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { RequestHandler } from 'kibana/server';
|
||||
import { ILicenseState, isErrorThatHandlesItsOwnResponse, verifyApiAccess } from '../lib';
|
||||
import { ActionsRequestHandlerContext } from '../types';
|
||||
|
||||
type ActionsRequestHandlerWrapper = <P, Q, B>(
|
||||
licenseState: ILicenseState,
|
||||
handler: RequestHandler<P, Q, B, ActionsRequestHandlerContext>
|
||||
) => RequestHandler<P, Q, B, ActionsRequestHandlerContext>;
|
||||
|
||||
export const verifyAccessAndContext: ActionsRequestHandlerWrapper = (licenseState, handler) => {
|
||||
return async (context, request, response) => {
|
||||
verifyApiAccess(licenseState);
|
||||
|
||||
if (!context.actions) {
|
||||
return response.badRequest({ body: 'RouteHandlerContext is not registered for actions' });
|
||||
}
|
||||
|
||||
try {
|
||||
return await handler(context, request, response);
|
||||
} catch (e) {
|
||||
if (isErrorThatHandlesItsOwnResponse(e)) {
|
||||
return e.sendResponse(response);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -18,11 +18,11 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should return 200 when creating an email action successfully', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An email action',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {
|
||||
service: '__json',
|
||||
from: 'bob@example.com',
|
||||
|
@ -38,9 +38,9 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
createdActionId = createdAction.id;
|
||||
expect(createdAction).to.eql({
|
||||
id: createdActionId,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'An email action',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {
|
||||
service: '__json',
|
||||
hasAuth: true,
|
||||
|
@ -54,14 +54,14 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
expect(typeof createdActionId).to.be('string');
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdActionId}`)
|
||||
.get(`/api/actions/connector/${createdActionId}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'An email action',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {
|
||||
from: 'bob@example.com',
|
||||
service: '__json',
|
||||
|
@ -75,7 +75,7 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should return the message data when firing the __json service', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${createdActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${createdActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -119,7 +119,7 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should render html from markdown', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${createdActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${createdActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -142,7 +142,7 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should allow customizing the kibana footer link', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${createdActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${createdActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -169,11 +169,11 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating an email action with an invalid config', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An email action',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {},
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -189,11 +189,11 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating an email action with a server not added to allowedHosts', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An email action',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {
|
||||
service: 'gmail', // not added to allowedHosts in the config for this test
|
||||
from: 'bob@example.com',
|
||||
|
@ -214,11 +214,11 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An email action',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {
|
||||
host: 'stmp.gmail.com', // not added to allowedHosts in the config for this test
|
||||
port: 666,
|
||||
|
@ -242,11 +242,11 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle creating an email action with a server added to allowedHosts', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An email action',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {
|
||||
host: 'some.non.existent.com', // added to allowedHosts in the config for this test
|
||||
port: 666,
|
||||
|
@ -263,11 +263,11 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle an email action with no auth', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An email action with no auth',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {
|
||||
service: '__json',
|
||||
from: 'jim@example.com',
|
||||
|
@ -276,7 +276,7 @@ export default function emailTest({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
|
||||
await supertest
|
||||
.post(`/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
|
|
@ -26,11 +26,11 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
it('should be created successfully', async () => {
|
||||
// create action with no config
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An index action',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
},
|
||||
|
@ -40,9 +40,9 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'An index action',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
refresh: false,
|
||||
|
@ -53,24 +53,24 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
expect(typeof createdActionID).to.be('string');
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdActionID}`)
|
||||
.get(`/api/actions/connector/${createdActionID}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'An index action',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: { index: ES_TEST_INDEX_NAME, refresh: false, executionTimeField: null },
|
||||
});
|
||||
|
||||
// create action with all config props
|
||||
const { body: createdActionWithIndex } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An index action with index config',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
refresh: true,
|
||||
|
@ -81,9 +81,9 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdActionWithIndex).to.eql({
|
||||
id: createdActionWithIndex.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'An index action with index config',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
refresh: true,
|
||||
|
@ -94,14 +94,14 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
expect(typeof createdActionIDWithIndex).to.be('string');
|
||||
|
||||
const { body: fetchedActionWithIndex } = await supertest
|
||||
.get(`/api/actions/action/${createdActionIDWithIndex}`)
|
||||
.get(`/api/actions/connector/${createdActionIDWithIndex}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedActionWithIndex).to.eql({
|
||||
id: fetchedActionWithIndex.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'An index action with index config',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
refresh: true,
|
||||
|
@ -112,11 +112,11 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with error when creation unsuccessful', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An index action',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: { index: 666 },
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -132,11 +132,11 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should execute successly when expected for a single body', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An index action',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
refresh: true,
|
||||
|
@ -145,7 +145,7 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.expect(200);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -162,11 +162,11 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should execute successly when expected for with multiple bodies', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An index action',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
refresh: true,
|
||||
|
@ -175,7 +175,7 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.expect(200);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -206,11 +206,11 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should execute successly with refresh false', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An index action',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
refresh: false,
|
||||
|
@ -220,7 +220,7 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.expect(200);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -235,11 +235,11 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
expect(items.length).to.be.lessThan(2);
|
||||
|
||||
const { body: createdActionWithRefresh } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An index action',
|
||||
actionTypeId: '.index',
|
||||
connector_type_id: '.index',
|
||||
config: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
refresh: true,
|
||||
|
@ -248,7 +248,7 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.expect(200);
|
||||
const { body: result2 } = await supertest
|
||||
.post(`/api/actions/action/${createdActionWithRefresh.id}/_execute`)
|
||||
.post(`/api/actions/connector/${createdActionWithRefresh.id}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
|
|
@ -24,7 +24,7 @@ export default function indexTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should execute successfully when expected for a single body', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${ACTION_ID}/_execute`)
|
||||
.post(`/api/actions/connector/${ACTION_ID}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
|
|
@ -60,11 +60,11 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
describe('Jira - Action Creation', () => {
|
||||
it('should return 200 when creating a jira action successfully', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A jira action',
|
||||
actionTypeId: '.jira',
|
||||
connector_type_id: '.jira',
|
||||
config: {
|
||||
...mockJira.config,
|
||||
apiUrl: jiraSimulatorURL,
|
||||
|
@ -75,9 +75,9 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A jira action',
|
||||
actionTypeId: '.jira',
|
||||
connector_type_id: '.jira',
|
||||
config: {
|
||||
apiUrl: jiraSimulatorURL,
|
||||
projectKey: mockJira.config.projectKey,
|
||||
|
@ -85,14 +85,14 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdAction.id}`)
|
||||
.get(`/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A jira action',
|
||||
actionTypeId: '.jira',
|
||||
connector_type_id: '.jira',
|
||||
config: {
|
||||
apiUrl: jiraSimulatorURL,
|
||||
projectKey: mockJira.config.projectKey,
|
||||
|
@ -102,11 +102,11 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a jira action with no apiUrl', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A jira action',
|
||||
actionTypeId: '.jira',
|
||||
connector_type_id: '.jira',
|
||||
config: { projectKey: 'CK' },
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -122,11 +122,11 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a jira action with no projectKey', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A jira action',
|
||||
actionTypeId: '.jira',
|
||||
connector_type_id: '.jira',
|
||||
config: { apiUrl: jiraSimulatorURL },
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -142,11 +142,11 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a jira action with a not present in allowedHosts apiUrl', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A jira action',
|
||||
actionTypeId: '.jira',
|
||||
connector_type_id: '.jira',
|
||||
config: {
|
||||
apiUrl: 'http://jira.mynonexistent.com',
|
||||
projectKey: mockJira.config.projectKey,
|
||||
|
@ -166,11 +166,11 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a jira action without secrets', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A jira action',
|
||||
actionTypeId: '.jira',
|
||||
connector_type_id: '.jira',
|
||||
config: {
|
||||
apiUrl: jiraSimulatorURL,
|
||||
projectKey: mockJira.config.projectKey,
|
||||
|
@ -195,11 +195,11 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
before(async () => {
|
||||
const { body } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A jira simulator',
|
||||
actionTypeId: '.jira',
|
||||
connector_type_id: '.jira',
|
||||
config: {
|
||||
apiUrl: jiraSimulatorURL,
|
||||
projectKey: mockJira.config.projectKey,
|
||||
|
@ -220,14 +220,14 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
describe('Validation', () => {
|
||||
it('should handle failing with a simulated success without action', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {},
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']);
|
||||
expect(resp.body.actionId).to.eql(simulatedActionId);
|
||||
expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']);
|
||||
expect(resp.body.connector_id).to.eql(simulatedActionId);
|
||||
expect(resp.body.status).to.eql('error');
|
||||
expect(resp.body.retry).to.eql(false);
|
||||
// Node.js 12 oddity:
|
||||
|
@ -261,14 +261,14 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without unsupported action', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: { subAction: 'non-supported' },
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -279,14 +279,14 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without subActionParams', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: { subAction: 'pushToService' },
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -297,7 +297,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without title', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -312,7 +312,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -323,7 +323,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without commentId', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -340,7 +340,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -351,7 +351,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without comment message', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -367,7 +367,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -378,7 +378,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success when labels containing a space', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -395,7 +395,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -408,7 +408,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
describe('Execution', () => {
|
||||
it('should handle creating an incident without comments', async () => {
|
||||
const { body } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -427,7 +427,7 @@ export default function jiraTest({ getService }: FtrProviderContext) {
|
|||
expect(proxyHaveBeenCalled).to.equal(true);
|
||||
expect(body).to.eql({
|
||||
status: 'ok',
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
data: {
|
||||
id: '123',
|
||||
title: 'CK-1',
|
||||
|
|
|
@ -45,11 +45,11 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should return successfully when passed valid create parameters', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A pagerduty action',
|
||||
actionTypeId: '.pagerduty',
|
||||
connector_type_id: '.pagerduty',
|
||||
config: {
|
||||
apiUrl: pagerdutySimulatorURL,
|
||||
},
|
||||
|
@ -61,9 +61,9 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A pagerduty action',
|
||||
actionTypeId: '.pagerduty',
|
||||
connector_type_id: '.pagerduty',
|
||||
config: {
|
||||
apiUrl: pagerdutySimulatorURL,
|
||||
},
|
||||
|
@ -72,14 +72,14 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
expect(typeof createdAction.id).to.be('string');
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdAction.id}`)
|
||||
.get(`/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A pagerduty action',
|
||||
actionTypeId: '.pagerduty',
|
||||
connector_type_id: '.pagerduty',
|
||||
config: {
|
||||
apiUrl: pagerdutySimulatorURL,
|
||||
},
|
||||
|
@ -88,11 +88,11 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should return unsuccessfully when passed invalid create parameters', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A pagerduty action',
|
||||
actionTypeId: '.pagerduty',
|
||||
connector_type_id: '.pagerduty',
|
||||
config: {
|
||||
apiUrl: pagerdutySimulatorURL,
|
||||
},
|
||||
|
@ -111,11 +111,11 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should return unsuccessfully when default pagerduty url is not present in allowedHosts', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A pagerduty action',
|
||||
actionTypeId: '.pagerduty',
|
||||
connector_type_id: '.pagerduty',
|
||||
secrets: {},
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -131,11 +131,11 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should create pagerduty simulator action successfully', async () => {
|
||||
const { body: createdSimulatedAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A pagerduty simulator',
|
||||
actionTypeId: '.pagerduty',
|
||||
connector_type_id: '.pagerduty',
|
||||
config: {
|
||||
apiUrl: pagerdutySimulatorURL,
|
||||
},
|
||||
|
@ -150,7 +150,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle executing with a simulated success', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -162,7 +162,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
expect(proxyHaveBeenCalled).to.equal(true);
|
||||
expect(result).to.eql({
|
||||
status: 'ok',
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
data: {
|
||||
message: 'Event processed',
|
||||
status: 'success',
|
||||
|
@ -172,7 +172,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle a 40x pagerduty error', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -186,7 +186,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle a 429 pagerduty error', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -204,7 +204,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle a 500 pagerduty error', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
|
|
@ -63,11 +63,11 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
describe('IBM Resilient - Action Creation', () => {
|
||||
it('should return 200 when creating a ibm resilient action successfully', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An IBM Resilient action',
|
||||
actionTypeId: '.resilient',
|
||||
connector_type_id: '.resilient',
|
||||
config: {
|
||||
...mockResilient.config,
|
||||
apiUrl: resilientSimulatorURL,
|
||||
|
@ -78,9 +78,9 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'An IBM Resilient action',
|
||||
actionTypeId: '.resilient',
|
||||
connector_type_id: '.resilient',
|
||||
config: {
|
||||
apiUrl: resilientSimulatorURL,
|
||||
orgId: mockResilient.config.orgId,
|
||||
|
@ -88,14 +88,14 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdAction.id}`)
|
||||
.get(`/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'An IBM Resilient action',
|
||||
actionTypeId: '.resilient',
|
||||
connector_type_id: '.resilient',
|
||||
config: {
|
||||
apiUrl: resilientSimulatorURL,
|
||||
orgId: mockResilient.config.orgId,
|
||||
|
@ -105,11 +105,11 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a ibm resilient action with no apiUrl', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An IBM Resilient',
|
||||
actionTypeId: '.resilient',
|
||||
connector_type_id: '.resilient',
|
||||
config: { orgId: '201' },
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -125,11 +125,11 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a ibm resilient action with no orgId', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An IBM Resilient',
|
||||
actionTypeId: '.resilient',
|
||||
connector_type_id: '.resilient',
|
||||
config: { apiUrl: resilientSimulatorURL },
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -145,11 +145,11 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a ibm resilient action with a not present in allowedHosts apiUrl', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An IBM Resilient',
|
||||
actionTypeId: '.resilient',
|
||||
connector_type_id: '.resilient',
|
||||
config: {
|
||||
apiUrl: 'http://resilient.mynonexistent.com',
|
||||
orgId: mockResilient.config.orgId,
|
||||
|
@ -169,11 +169,11 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a ibm resilient action without secrets', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'An IBM Resilient',
|
||||
actionTypeId: '.resilient',
|
||||
connector_type_id: '.resilient',
|
||||
config: {
|
||||
apiUrl: resilientSimulatorURL,
|
||||
orgId: mockResilient.config.orgId,
|
||||
|
@ -197,11 +197,11 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
let proxyHaveBeenCalled = false;
|
||||
before(async () => {
|
||||
const { body } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A ibm resilient simulator',
|
||||
actionTypeId: '.resilient',
|
||||
connector_type_id: '.resilient',
|
||||
config: {
|
||||
apiUrl: resilientSimulatorURL,
|
||||
orgId: mockResilient.config.orgId,
|
||||
|
@ -222,14 +222,14 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
describe('Validation', () => {
|
||||
it('should handle failing with a simulated success without action', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {},
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']);
|
||||
expect(resp.body.actionId).to.eql(simulatedActionId);
|
||||
expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']);
|
||||
expect(resp.body.connector_id).to.eql(simulatedActionId);
|
||||
expect(resp.body.status).to.eql('error');
|
||||
expect(resp.body.retry).to.eql(false);
|
||||
// Node.js 12 oddity:
|
||||
|
@ -263,14 +263,14 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without unsupported action', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: { subAction: 'non-supported' },
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -281,14 +281,14 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without subActionParams', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: { subAction: 'pushToService' },
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -299,7 +299,7 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without title', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -314,7 +314,7 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -325,7 +325,7 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without commentId', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -341,7 +341,7 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -352,7 +352,7 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without comment message', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -368,7 +368,7 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -381,7 +381,7 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
describe('Execution', () => {
|
||||
it('should handle creating an incident without comments', async () => {
|
||||
const { body } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -397,7 +397,7 @@ export default function resilientTest({ getService }: FtrProviderContext) {
|
|||
expect(proxyHaveBeenCalled).to.equal(true);
|
||||
expect(body).to.eql({
|
||||
status: 'ok',
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
data: {
|
||||
id: '123',
|
||||
title: '123',
|
||||
|
|
|
@ -18,41 +18,41 @@ export default function serverLogTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should return 200 when creating a builtin server-log action', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A server.log action',
|
||||
actionTypeId: '.server-log',
|
||||
connector_type_id: '.server-log',
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
serverLogActionId = createdAction.id;
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A server.log action',
|
||||
actionTypeId: '.server-log',
|
||||
connector_type_id: '.server-log',
|
||||
config: {},
|
||||
});
|
||||
|
||||
expect(typeof createdAction.id).to.be('string');
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdAction.id}`)
|
||||
.get(`/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A server.log action',
|
||||
actionTypeId: '.server-log',
|
||||
connector_type_id: '.server-log',
|
||||
config: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle firing the action', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${serverLogActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${serverLogActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
|
|
@ -65,11 +65,11 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
describe('ServiceNow - Action Creation', () => {
|
||||
it('should return 200 when creating a servicenow action successfully', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A servicenow action',
|
||||
actionTypeId: '.servicenow',
|
||||
connector_type_id: '.servicenow',
|
||||
config: {
|
||||
apiUrl: servicenowSimulatorURL,
|
||||
},
|
||||
|
@ -79,23 +79,23 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A servicenow action',
|
||||
actionTypeId: '.servicenow',
|
||||
connector_type_id: '.servicenow',
|
||||
config: {
|
||||
apiUrl: servicenowSimulatorURL,
|
||||
},
|
||||
});
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdAction.id}`)
|
||||
.get(`/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A servicenow action',
|
||||
actionTypeId: '.servicenow',
|
||||
connector_type_id: '.servicenow',
|
||||
config: {
|
||||
apiUrl: servicenowSimulatorURL,
|
||||
},
|
||||
|
@ -104,11 +104,11 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a servicenow action with no apiUrl', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A servicenow action',
|
||||
actionTypeId: '.servicenow',
|
||||
connector_type_id: '.servicenow',
|
||||
config: {},
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -124,11 +124,11 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a servicenow action with a not present in allowedHosts apiUrl', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A servicenow action',
|
||||
actionTypeId: '.servicenow',
|
||||
connector_type_id: '.servicenow',
|
||||
config: {
|
||||
apiUrl: 'http://servicenow.mynonexistent.com',
|
||||
},
|
||||
|
@ -147,11 +147,11 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a servicenow action without secrets', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A servicenow action',
|
||||
actionTypeId: '.servicenow',
|
||||
connector_type_id: '.servicenow',
|
||||
config: {
|
||||
apiUrl: servicenowSimulatorURL,
|
||||
},
|
||||
|
@ -174,11 +174,11 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
let proxyHaveBeenCalled = false;
|
||||
before(async () => {
|
||||
const { body } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A servicenow simulator',
|
||||
actionTypeId: '.servicenow',
|
||||
connector_type_id: '.servicenow',
|
||||
config: {
|
||||
apiUrl: servicenowSimulatorURL,
|
||||
},
|
||||
|
@ -198,14 +198,14 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
describe('Validation', () => {
|
||||
it('should handle failing with a simulated success without action', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {},
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']);
|
||||
expect(resp.body.actionId).to.eql(simulatedActionId);
|
||||
expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']);
|
||||
expect(resp.body.connector_id).to.eql(simulatedActionId);
|
||||
expect(resp.body.status).to.eql('error');
|
||||
expect(resp.body.retry).to.eql(false);
|
||||
// Node.js 12 oddity:
|
||||
|
@ -239,14 +239,14 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without unsupported action', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: { subAction: 'non-supported' },
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -257,14 +257,14 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without subActionParams', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: { subAction: 'pushToService' },
|
||||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -275,7 +275,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without title', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -287,7 +287,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -298,7 +298,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without commentId', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -314,7 +314,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -325,7 +325,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failing with a simulated success without comment message', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -341,7 +341,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -353,7 +353,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
describe('getChoices', () => {
|
||||
it('should fail when field is not provided', async () => {
|
||||
await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -363,7 +363,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.then((resp: any) => {
|
||||
expect(resp.body).to.eql({
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
status: 'error',
|
||||
retry: false,
|
||||
message:
|
||||
|
@ -377,7 +377,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
describe('Execution', () => {
|
||||
it('should handle creating an incident without comments', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -393,7 +393,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
expect(proxyHaveBeenCalled).to.equal(true);
|
||||
expect(result).to.eql({
|
||||
status: 'ok',
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
data: {
|
||||
id: '123',
|
||||
title: 'INC01',
|
||||
|
@ -406,7 +406,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
describe('getChoices', () => {
|
||||
it('should get choices', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -419,7 +419,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) {
|
|||
expect(proxyHaveBeenCalled).to.equal(true);
|
||||
expect(result).to.eql({
|
||||
status: 'ok',
|
||||
actionId: simulatedActionId,
|
||||
connector_id: simulatedActionId,
|
||||
data: [
|
||||
{
|
||||
dependent_value: '',
|
||||
|
|
|
@ -45,11 +45,11 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should return 200 when creating a slack action successfully', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A slack action',
|
||||
actionTypeId: '.slack',
|
||||
connector_type_id: '.slack',
|
||||
secrets: {
|
||||
webhookUrl: slackSimulatorURL,
|
||||
},
|
||||
|
@ -58,34 +58,34 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A slack action',
|
||||
actionTypeId: '.slack',
|
||||
connector_type_id: '.slack',
|
||||
config: {},
|
||||
});
|
||||
|
||||
expect(typeof createdAction.id).to.be('string');
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdAction.id}`)
|
||||
.get(`/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A slack action',
|
||||
actionTypeId: '.slack',
|
||||
connector_type_id: '.slack',
|
||||
config: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('should respond with a 400 Bad Request when creating a slack action with no webhookUrl', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A slack action',
|
||||
actionTypeId: '.slack',
|
||||
connector_type_id: '.slack',
|
||||
secrets: {},
|
||||
})
|
||||
.expect(400)
|
||||
|
@ -101,11 +101,11 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a slack action with not present in allowedHosts webhookUrl', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A slack action',
|
||||
actionTypeId: '.slack',
|
||||
connector_type_id: '.slack',
|
||||
secrets: {
|
||||
webhookUrl: 'http://slack.mynonexistent.com/other/stuff/in/the/path',
|
||||
},
|
||||
|
@ -122,11 +122,11 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should respond with a 400 Bad Request when creating a slack action with a webhookUrl with no hostname', async () => {
|
||||
await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A slack action',
|
||||
actionTypeId: '.slack',
|
||||
connector_type_id: '.slack',
|
||||
secrets: {
|
||||
webhookUrl: 'fee-fi-fo-fum',
|
||||
},
|
||||
|
@ -144,11 +144,11 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should create our slack simulator action successfully', async () => {
|
||||
const { body: createdSimulatedAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A slack simulator',
|
||||
actionTypeId: '.slack',
|
||||
connector_type_id: '.slack',
|
||||
secrets: {
|
||||
webhookUrl: slackSimulatorURL,
|
||||
},
|
||||
|
@ -160,7 +160,7 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle firing with a simulated success', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -174,7 +174,7 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle an empty message error', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -188,7 +188,7 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle a 40x slack error', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -203,7 +203,7 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
it('should handle a 429 slack error', async () => {
|
||||
const dateStart = new Date().getTime();
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -221,7 +221,7 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle a 500 slack error', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${simulatedActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${simulatedActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
|
|
@ -54,11 +54,11 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
};
|
||||
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
name: 'A generic Webhook action',
|
||||
actionTypeId: '.webhook',
|
||||
connector_type_id: '.webhook',
|
||||
secrets: {
|
||||
user,
|
||||
password,
|
||||
|
@ -99,11 +99,11 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should return 200 when creating a webhook action successfully', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
name: 'A generic Webhook action',
|
||||
actionTypeId: '.webhook',
|
||||
connector_type_id: '.webhook',
|
||||
secrets: {
|
||||
user: 'username',
|
||||
password: 'mypassphrase',
|
||||
|
@ -116,9 +116,9 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A generic Webhook action',
|
||||
actionTypeId: '.webhook',
|
||||
connector_type_id: '.webhook',
|
||||
config: {
|
||||
...defaultValues,
|
||||
url: webhookSimulatorURL,
|
||||
|
@ -128,14 +128,14 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
expect(typeof createdAction.id).to.be('string');
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdAction.id}`)
|
||||
.get(`/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A generic Webhook action',
|
||||
actionTypeId: '.webhook',
|
||||
connector_type_id: '.webhook',
|
||||
config: {
|
||||
...defaultValues,
|
||||
url: webhookSimulatorURL,
|
||||
|
@ -145,11 +145,11 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should remove headers when a webhook is updated', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
name: 'A generic Webhook action',
|
||||
actionTypeId: '.webhook',
|
||||
connector_type_id: '.webhook',
|
||||
secrets: {
|
||||
user: 'username',
|
||||
password: 'mypassphrase',
|
||||
|
@ -165,9 +165,9 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(createdAction).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A generic Webhook action',
|
||||
actionTypeId: '.webhook',
|
||||
connector_type_id: '.webhook',
|
||||
config: {
|
||||
...defaultValues,
|
||||
url: webhookSimulatorURL,
|
||||
|
@ -178,7 +178,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
await supertest
|
||||
.put(`/api/actions/action/${createdAction.id}`)
|
||||
.put(`/api/actions/connector/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'A generic Webhook action',
|
||||
|
@ -196,14 +196,14 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
|
||||
const { body: fetchedAction } = await supertest
|
||||
.get(`/api/actions/action/${createdAction.id}`)
|
||||
.get(`/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200);
|
||||
|
||||
expect(fetchedAction).to.eql({
|
||||
id: fetchedAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'A generic Webhook action',
|
||||
actionTypeId: '.webhook',
|
||||
connector_type_id: '.webhook',
|
||||
config: {
|
||||
...defaultValues,
|
||||
url: webhookSimulatorURL,
|
||||
|
@ -217,7 +217,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
it('should send authentication to the webhook target', async () => {
|
||||
const webhookActionId = await createWebhookAction(webhookSimulatorURL, {}, kibanaURL);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -236,7 +236,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
kibanaURL
|
||||
);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -255,7 +255,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
kibanaURL
|
||||
);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -270,11 +270,11 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle target webhooks that are not added to allowedHosts', async () => {
|
||||
const { body: result } = await supertest
|
||||
.post('/api/actions/action')
|
||||
.post('/api/actions/connector')
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
name: 'A generic Webhook action',
|
||||
actionTypeId: '.webhook',
|
||||
connector_type_id: '.webhook',
|
||||
secrets: {
|
||||
user: 'username',
|
||||
password: 'mypassphrase',
|
||||
|
@ -296,7 +296,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
kibanaURL
|
||||
);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -312,7 +312,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
it('should handle failing webhook targets', async () => {
|
||||
const webhookActionId = await createWebhookAction(webhookSimulatorURL, {}, kibanaURL);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.post(`/api/actions/connector/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -323,7 +323,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(result.status).to.eql('error');
|
||||
expect(result.message).to.match(/error calling webhook, retry later/);
|
||||
expect(result.serviceMessage).to.eql('[500] Internal Server Error');
|
||||
expect(result.service_message).to.eql('[500] Internal Server Error');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
|
|
@ -20,7 +20,7 @@ export default function listActionTypesTests({ getService }: FtrProviderContext)
|
|||
describe(scenario.id, () => {
|
||||
it('should return 200 with list of action types containing defaults', async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions/list_action_types`)
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions/connector_types`)
|
||||
.auth(user.username, user.password);
|
||||
|
||||
function createActionTypeMatcher(id: string, name: string) {
|
|
@ -25,12 +25,12 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
describe(scenario.id, () => {
|
||||
it('should handle create action request appropriately', async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -58,9 +58,9 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, response.body.id, 'action', 'actions');
|
||||
expect(response.body).to.eql({
|
||||
id: response.body.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -81,12 +81,12 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`should handle create action request appropriately when action type isn't registered`, async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.unregistered-action-type',
|
||||
connector_type_id: 'test.unregistered-action-type',
|
||||
config: {},
|
||||
});
|
||||
|
||||
|
@ -119,7 +119,7 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle create action request appropriately when payload is empty and invalid', async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({});
|
||||
|
@ -146,12 +146,12 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`should handle create action request appropriately when config isn't valid`, async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({
|
||||
name: 'my name',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: 'my unencrypted text',
|
||||
},
|
||||
|
@ -187,12 +187,12 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`should handle create action requests for action types that are not enabled`, async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({
|
||||
name: 'my name',
|
||||
actionTypeId: 'test.not-enabled',
|
||||
connector_type_id: 'test.not-enabled',
|
||||
});
|
||||
|
||||
switch (scenario.id) {
|
||||
|
|
|
@ -26,11 +26,11 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
describe(scenario.id, () => {
|
||||
it('should handle delete action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -41,7 +41,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.delete(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}`)
|
||||
.delete(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo');
|
||||
|
||||
|
@ -71,11 +71,11 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't delete action from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -87,7 +87,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.delete(`${getUrlPrefix('other')}/api/actions/action/${createdAction.id}`)
|
||||
.delete(`${getUrlPrefix('other')}/api/actions/connector/${createdAction.id}`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo');
|
||||
|
||||
|
@ -120,7 +120,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`should handle delete request appropriately when action doesn't exist`, async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.delete(`${getUrlPrefix(space.id)}/api/actions/action/2`)
|
||||
.delete(`${getUrlPrefix(space.id)}/api/actions/connector/2`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password);
|
||||
|
||||
|
@ -148,7 +148,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't delete action from preconfigured list`, async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.delete(`${getUrlPrefix(space.id)}/api/actions/action/my-slack1`)
|
||||
.delete(`${getUrlPrefix(space.id)}/api/actions/connector/my-slack1`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo');
|
||||
|
||||
|
|
|
@ -48,11 +48,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
describe(scenario.id, () => {
|
||||
it('should handle execute request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -65,7 +65,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
const reference = `actions-execute-1:${user.username}`;
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
@ -117,7 +117,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
await validateEventLog({
|
||||
spaceId: space.id,
|
||||
actionId: createdAction.id,
|
||||
connectorId: createdAction.id,
|
||||
outcome: 'success',
|
||||
message: `action executed: test.index-record:${createdAction.id}: My action`,
|
||||
});
|
||||
|
@ -129,11 +129,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't execute an action from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -146,7 +146,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
const reference = `actions-execute-4:${user.username}`;
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix('other')}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`${getUrlPrefix('other')}/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
@ -186,11 +186,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle execute request appropriately after action is updated', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -202,7 +202,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}`)
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action updated',
|
||||
|
@ -217,7 +217,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
const reference = `actions-execute-2:${user.username}`;
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
@ -274,7 +274,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`should handle execute request appropriately when action doesn't exist`, async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action/1/_execute`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector/1/_execute`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
@ -310,7 +310,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle execute request appropriately when payload is empty and invalid', async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action/1/_execute`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector/1/_execute`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({});
|
||||
|
@ -338,11 +338,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle execute request appropriately after changing config properties', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'test email action',
|
||||
actionTypeId: '.email',
|
||||
connector_type_id: '.email',
|
||||
config: {
|
||||
from: 'email-from-1@example.com',
|
||||
// this host is specifically added to allowedHosts in:
|
||||
|
@ -359,7 +359,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}`)
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'a test email action 2',
|
||||
|
@ -375,7 +375,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
@ -413,17 +413,17 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
let searchResult: any;
|
||||
const reference = `actions-execute-3:${user.username}`;
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.authorization',
|
||||
connector_type_id: 'test.authorization',
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}/_execute`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
@ -503,21 +503,21 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
interface ValidateEventLogParams {
|
||||
spaceId: string;
|
||||
actionId: string;
|
||||
connectorId: string;
|
||||
outcome: string;
|
||||
message: string;
|
||||
errorMessage?: string;
|
||||
}
|
||||
|
||||
async function validateEventLog(params: ValidateEventLogParams): Promise<void> {
|
||||
const { spaceId, actionId, outcome, message, errorMessage } = params;
|
||||
const { spaceId, connectorId, outcome, message, errorMessage } = params;
|
||||
|
||||
const events: IValidatedEvent[] = await retry.try(async () => {
|
||||
return await getEventLog({
|
||||
getService,
|
||||
spaceId,
|
||||
type: 'action',
|
||||
id: actionId,
|
||||
id: connectorId,
|
||||
provider: 'actions',
|
||||
actions: new Map([['execute', { equal: 1 }]]),
|
||||
filter: 'event.action:(execute)',
|
||||
|
@ -550,7 +550,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
{
|
||||
rel: 'primary',
|
||||
type: 'action',
|
||||
id: actionId,
|
||||
id: connectorId,
|
||||
namespace: spaceId,
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -25,11 +25,11 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
describe(scenario.id, () => {
|
||||
it('should handle get action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -41,7 +41,7 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}`)
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.auth(user.username, user.password);
|
||||
|
||||
switch (scenario.id) {
|
||||
|
@ -62,8 +62,8 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
expect(response.statusCode).to.eql(200);
|
||||
expect(response.body).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: false,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'My action',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
|
@ -77,11 +77,11 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`action shouldn't be acessible from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -93,7 +93,7 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.get(`${getUrlPrefix('other')}/api/actions/action/${createdAction.id}`)
|
||||
.get(`${getUrlPrefix('other')}/api/actions/connector/${createdAction.id}`)
|
||||
.auth(user.username, user.password);
|
||||
|
||||
switch (scenario.id) {
|
||||
|
@ -125,7 +125,7 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle get preconfigured action request appropriately', async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions/action/my-slack1`)
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions/connector/my-slack1`)
|
||||
.auth(user.username, user.password);
|
||||
|
||||
switch (scenario.id) {
|
||||
|
@ -146,9 +146,9 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
expect(response.statusCode).to.eql(200);
|
||||
expect(response.body).to.eql({
|
||||
id: 'my-slack1',
|
||||
actionTypeId: '.slack',
|
||||
connector_type_id: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
isPreconfigured: true,
|
||||
is_preconfigured: true,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -25,11 +25,11 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
describe(scenario.id, () => {
|
||||
it('should handle get all action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -41,7 +41,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions`)
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions/connectors`)
|
||||
.auth(user.username, user.password);
|
||||
|
||||
switch (scenario.id) {
|
||||
|
@ -63,41 +63,41 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
expect(response.body).to.eql([
|
||||
{
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured-es-index-action',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.index',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.index',
|
||||
name: 'preconfigured_es_index_action',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'my-slack1',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.slack',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'custom-system-abc-connector',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'system-abc-action-type',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'system-abc-action-type',
|
||||
name: 'SystemABC',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured.test.index-record',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'Test:_Preconfigured_Index_Record',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
|
@ -106,13 +106,13 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
}
|
||||
});
|
||||
|
||||
it('should handle get all request appropriately with proper referencedByCount', async () => {
|
||||
it('should handle get all request appropriately with proper referenced_by_count', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -148,7 +148,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAlert.id, 'alert', 'alerts');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions`)
|
||||
.get(`${getUrlPrefix(space.id)}/api/actions/connectors`)
|
||||
.auth(user.username, user.password);
|
||||
|
||||
switch (scenario.id) {
|
||||
|
@ -170,41 +170,41 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
expect(response.body).to.eql([
|
||||
{
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
referencedByCount: 1,
|
||||
referenced_by_count: 1,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured-es-index-action',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.index',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.index',
|
||||
name: 'preconfigured_es_index_action',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'my-slack1',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.slack',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
referencedByCount: 1,
|
||||
referenced_by_count: 1,
|
||||
},
|
||||
{
|
||||
id: 'custom-system-abc-connector',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'system-abc-action-type',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'system-abc-action-type',
|
||||
name: 'SystemABC',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured.test.index-record',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'Test:_Preconfigured_Index_Record',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
|
@ -215,11 +215,11 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't get actions from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -231,7 +231,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.get(`${getUrlPrefix('other')}/api/actions`)
|
||||
.get(`${getUrlPrefix('other')}/api/actions/connectors`)
|
||||
.auth(user.username, user.password);
|
||||
|
||||
switch (scenario.id) {
|
||||
|
@ -253,31 +253,31 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
expect(response.body).to.eql([
|
||||
{
|
||||
id: 'preconfigured-es-index-action',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.index',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.index',
|
||||
name: 'preconfigured_es_index_action',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'my-slack1',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.slack',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'custom-system-abc-connector',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'system-abc-action-type',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'system-abc-action-type',
|
||||
name: 'SystemABC',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured.test.index-record',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'Test:_Preconfigured_Index_Record',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
|
|
|
@ -34,7 +34,7 @@ export default function actionsTests({ loadTestFile, getService }: FtrProviderCo
|
|||
loadTestFile(require.resolve('./execute'));
|
||||
loadTestFile(require.resolve('./get_all'));
|
||||
loadTestFile(require.resolve('./get'));
|
||||
loadTestFile(require.resolve('./list_action_types'));
|
||||
loadTestFile(require.resolve('./connector_types'));
|
||||
loadTestFile(require.resolve('./update'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ if (require.main === module) main();
|
|||
async function main() {
|
||||
let response;
|
||||
|
||||
response = await httpPost('api/actions/action', {
|
||||
actionTypeId: '.email',
|
||||
response = await httpPost('api/actions/connector', {
|
||||
connector_type_id: '.email',
|
||||
name: 'an email action',
|
||||
config: {
|
||||
from: 'patrick.mueller@elastic.co',
|
||||
|
@ -32,12 +32,12 @@ async function main() {
|
|||
});
|
||||
console.log(`result of create: ${JSON.stringify(response, null, 4)}`);
|
||||
|
||||
const actionId = response.id;
|
||||
const connectorId = response.id;
|
||||
|
||||
response = await httpGet(`api/actions/${actionId}`);
|
||||
response = await httpGet(`api/actions/${connectorId}`);
|
||||
console.log(`action after create: ${JSON.stringify(response, null, 4)}`);
|
||||
|
||||
response = await httpPut(`api/actions/action/${actionId}`, {
|
||||
response = await httpPut(`api/actions/connector/${connectorId}`, {
|
||||
name: 'an email action',
|
||||
config: {
|
||||
from: 'patrick.mueller@elastic.co',
|
||||
|
@ -51,10 +51,10 @@ async function main() {
|
|||
|
||||
console.log(`response from update: ${JSON.stringify(response, null, 4)}`);
|
||||
|
||||
response = await httpGet(`api/actions/${actionId}`);
|
||||
response = await httpGet(`api/actions/${connectorId}`);
|
||||
console.log(`action after update: ${JSON.stringify(response, null, 4)}`);
|
||||
|
||||
response = await httpPost(`api/actions/action/${actionId}/_execute`, {
|
||||
response = await httpPost(`api/actions/connector/${connectorId}/_execute`, {
|
||||
params: {
|
||||
to: ['patrick.mueller@elastic.co'],
|
||||
subject: 'the email subject',
|
||||
|
|
|
@ -25,11 +25,11 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
describe(scenario.id, () => {
|
||||
it('should handle update action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -41,7 +41,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}`)
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
@ -72,8 +72,8 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
expect(response.statusCode).to.eql(200);
|
||||
expect(response.body).to.eql({
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: false,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'My action updated',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
|
@ -94,11 +94,11 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't update action from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -110,7 +110,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.put(`${getUrlPrefix('other')}/api/actions/action/${createdAction.id}`)
|
||||
.put(`${getUrlPrefix('other')}/api/actions/connector/${createdAction.id}`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
@ -152,7 +152,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle update action request appropriately when passing a null config', async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/action/1`)
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/connector/1`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({
|
||||
|
@ -182,7 +182,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`should handle update action request appropriately when action doesn't exist`, async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/action/1`)
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/connector/1`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({
|
||||
|
@ -224,7 +224,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle update action request appropriately when payload is empty and invalid', async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/action/1`)
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/connector/1`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({});
|
||||
|
@ -252,11 +252,11 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle update action request appropriately when secrets are not valid', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -268,7 +268,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/action/${createdAction.id}`)
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({
|
||||
|
@ -311,7 +311,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't update action from preconfigured list`, async () => {
|
||||
const response = await supertestWithoutAuth
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/action/custom-system-abc-connector`)
|
||||
.put(`${getUrlPrefix(space.id)}/api/actions/connector/custom-system-abc-connector`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
|
|
|
@ -14,10 +14,10 @@ import { FtrProviderContext } from '../../../common/ftr_provider_context';
|
|||
export default function listActionTypesTests({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('list_action_types', () => {
|
||||
it('should return 200 with list of action types containing defaults', async () => {
|
||||
describe('connector_types', () => {
|
||||
it('should return 200 with list of connector types containing defaults', async () => {
|
||||
const response = await supertest.get(
|
||||
`${getUrlPrefix(Spaces.space1.id)}/api/actions/list_action_types`
|
||||
`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector_types`
|
||||
);
|
||||
|
||||
function createActionTypeMatcher(id: string, name: string) {
|
||||
|
@ -33,5 +33,26 @@ export default function listActionTypesTests({ getService }: FtrProviderContext)
|
|||
response.body.some(createActionTypeMatcher('test.index-record', 'Test: Index Record'))
|
||||
).to.be(true);
|
||||
});
|
||||
|
||||
describe('legacy', () => {
|
||||
it('should return 200 with list of action types containing defaults', async () => {
|
||||
const response = await supertest.get(
|
||||
`${getUrlPrefix(Spaces.space1.id)}/api/actions/list_action_types`
|
||||
);
|
||||
|
||||
function createActionTypeMatcher(id: string, name: string) {
|
||||
return (actionType: { id: string; name: string }) => {
|
||||
return actionType.id === id && actionType.name === name;
|
||||
};
|
||||
}
|
||||
|
||||
expect(response.status).to.eql(200);
|
||||
// Check for values explicitly in order to avoid this test failing each time plugins register
|
||||
// a new action type
|
||||
expect(
|
||||
response.body.some(createActionTypeMatcher('test.index-record', 'Test: Index Record'))
|
||||
).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -19,13 +19,13 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
after(() => objectRemover.removeAll());
|
||||
|
||||
it('should handle create action request appropriately', async () => {
|
||||
it('should handle create connector request appropriately', async () => {
|
||||
const response = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -38,9 +38,9 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(Spaces.space1.id, response.body.id, 'action', 'actions');
|
||||
expect(response.body).to.eql({
|
||||
id: response.body.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -56,6 +56,45 @@ export default function createActionTests({ getService }: FtrProviderContext) {
|
|||
});
|
||||
});
|
||||
|
||||
describe('legacy', () => {
|
||||
it('should handle create action request appropriately', async () => {
|
||||
const response = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.eql(200);
|
||||
objectRemover.add(Spaces.space1.id, response.body.id, 'action', 'actions');
|
||||
expect(response.body).to.eql({
|
||||
id: response.body.id,
|
||||
isPreconfigured: false,
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
});
|
||||
expect(typeof response.body.id).to.be('string');
|
||||
|
||||
// Ensure AAD isn't broken
|
||||
await checkAAD({
|
||||
supertest,
|
||||
spaceId: Spaces.space1.id,
|
||||
type: 'action',
|
||||
id: response.body.id,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should notify feature usage when creating a gold action type', async () => {
|
||||
const testStart = new Date();
|
||||
const response = await supertest
|
||||
|
|
|
@ -20,11 +20,11 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle delete action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -35,18 +35,18 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
|
||||
await supertest
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}`)
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(204, '');
|
||||
});
|
||||
|
||||
it(`shouldn't delete action from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -58,7 +58,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.delete(`${getUrlPrefix(Spaces.other.id)}/api/actions/action/${createdAction.id}`)
|
||||
.delete(`${getUrlPrefix(Spaces.other.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
|
@ -69,7 +69,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`should handle delete request appropriately when action doesn't exist`, async () => {
|
||||
await supertest
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/2`)
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/2`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
|
@ -80,7 +80,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't delete action from preconfigured list`, async () => {
|
||||
await supertest
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/my-slack1`)
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/my-slack1`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(400, {
|
||||
statusCode: 400,
|
||||
|
@ -88,5 +88,78 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
message: `Preconfigured action my-slack1 is not allowed to delete.`,
|
||||
});
|
||||
});
|
||||
|
||||
describe('legacy', () => {
|
||||
it('should handle delete action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
await supertest
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(204, '');
|
||||
});
|
||||
|
||||
it(`shouldn't delete action from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.delete(`${getUrlPrefix(Spaces.other.id)}/api/actions/action/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
message: `Saved object [action/${createdAction.id}] not found`,
|
||||
});
|
||||
});
|
||||
|
||||
it(`should handle delete request appropriately when action doesn't exist`, async () => {
|
||||
await supertest
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/2`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
message: 'Saved object [action/2] not found',
|
||||
});
|
||||
});
|
||||
|
||||
it(`shouldn't delete action from preconfigured list`, async () => {
|
||||
await supertest
|
||||
.delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/my-slack1`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(400, {
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: `Preconfigured action my-slack1 is not allowed to delete.`,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -44,11 +44,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle execute request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -59,9 +59,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const reference = `actions-execute-1:${Spaces.space1.id}`;
|
||||
const reference = `actions-execute-1:${Spaces.space1.id}:${createdAction.id}`;
|
||||
const response = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(
|
||||
`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/${createdAction.id}/_execute`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -102,18 +104,20 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle failed executions', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'failing action',
|
||||
actionTypeId: 'test.failing',
|
||||
connector_type_id: 'test.failing',
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const reference = `actions-failure-1:${Spaces.space1.id}`;
|
||||
const response = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(
|
||||
`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/${createdAction.id}/_execute`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -124,10 +128,10 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(response.status).to.eql(200);
|
||||
expect(response.body).to.eql({
|
||||
actionId: createdAction.id,
|
||||
connector_id: createdAction.id,
|
||||
status: 'error',
|
||||
message: 'an error occurred while running the action executor',
|
||||
serviceMessage: `expected failure for ${ES_TEST_INDEX_NAME} ${reference}`,
|
||||
service_message: `expected failure for ${ES_TEST_INDEX_NAME} ${reference}`,
|
||||
retry: false,
|
||||
});
|
||||
|
||||
|
@ -142,11 +146,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't execute an action from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -178,17 +182,19 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
it('should handle execute request appropriately and have proper callCluster and savedObjectsClient authorization', async () => {
|
||||
const reference = `actions-execute-3:${Spaces.space1.id}`;
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.authorization',
|
||||
connector_type_id: 'test.authorization',
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const response = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(
|
||||
`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/${createdAction.id}/_execute`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
|
@ -220,11 +226,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should notify feature usage when executing a gold action type', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'Noop action type',
|
||||
actionTypeId: 'test.noop',
|
||||
connector_type_id: 'test.noop',
|
||||
secrets: {},
|
||||
config: {},
|
||||
})
|
||||
|
@ -233,7 +239,9 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
const executionStart = new Date();
|
||||
await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.post(
|
||||
`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/${createdAction.id}/_execute`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {},
|
||||
|
@ -251,6 +259,72 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(noopFeature.last_used).to.be.a('string');
|
||||
expect(new Date(noopFeature.last_used).getTime()).to.be.greaterThan(executionStart.getTime());
|
||||
});
|
||||
|
||||
describe('legacy', () => {
|
||||
it('should handle execute request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const reference = `actions-execute-1:${Spaces.space1.id}:${createdAction.id}`;
|
||||
const response = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
reference,
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
message: 'Testing 123',
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.eql(200);
|
||||
});
|
||||
|
||||
it('should handle failed executions', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'failing action',
|
||||
actionTypeId: 'test.failing',
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const reference = `actions-failure-1:${Spaces.space1.id}:${createdAction.id}`;
|
||||
const response = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}/_execute`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params: {
|
||||
reference,
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.eql(200);
|
||||
expect(response.body).to.eql({
|
||||
actionId: createdAction.id,
|
||||
status: 'error',
|
||||
message: 'an error occurred while running the action executor',
|
||||
serviceMessage: `expected failure for ${ES_TEST_INDEX_NAME} ${reference}`,
|
||||
retry: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
interface ValidateEventLogParams {
|
||||
|
|
|
@ -20,11 +20,11 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle get action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -36,11 +36,11 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}`)
|
||||
.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.expect(200, {
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: false,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'My action',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
|
@ -50,11 +50,11 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`action should't be acessible from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -66,7 +66,7 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.get(`${getUrlPrefix(Spaces.other.id)}/api/actions/action/${createdAction.id}`)
|
||||
.get(`${getUrlPrefix(Spaces.other.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
|
@ -76,13 +76,82 @@ export default function getActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle get action request from preconfigured list', async () => {
|
||||
await supertest
|
||||
.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/my-slack1`)
|
||||
.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/my-slack1`)
|
||||
.expect(200, {
|
||||
id: 'my-slack1',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.slack',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
});
|
||||
});
|
||||
|
||||
describe('legacy', () => {
|
||||
it('should handle get action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}`)
|
||||
.expect(200, {
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
actionTypeId: 'test.index-record',
|
||||
name: 'My action',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it(`action should't be acessible from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.get(`${getUrlPrefix(Spaces.other.id)}/api/actions/action/${createdAction.id}`)
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
message: `Saved object [action/${createdAction.id}] not found`,
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle get action request from preconfigured list', async () => {
|
||||
await supertest
|
||||
.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/my-slack1`)
|
||||
.expect(200, {
|
||||
id: 'my-slack1',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,44 +35,44 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions`).expect(200, [
|
||||
await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connectors`).expect(200, [
|
||||
{
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
is_preconfigured: false,
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured-es-index-action',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.index',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.index',
|
||||
name: 'preconfigured_es_index_action',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'my-slack1',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.slack',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'custom-system-abc-connector',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'system-abc-action-type',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'system-abc-action-type',
|
||||
name: 'SystemABC',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured.test.index-record',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'Test:_Preconfigured_Index_Record',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -94,36 +94,97 @@ export default function getAllActionTests({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest.get(`${getUrlPrefix(Spaces.other.id)}/api/actions`).expect(200, [
|
||||
await supertest.get(`${getUrlPrefix(Spaces.other.id)}/api/actions/connectors`).expect(200, [
|
||||
{
|
||||
id: 'preconfigured-es-index-action',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.index',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.index',
|
||||
name: 'preconfigured_es_index_action',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'my-slack1',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.slack',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'custom-system-abc-connector',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'system-abc-action-type',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'system-abc-action-type',
|
||||
name: 'SystemABC',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured.test.index-record',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: true,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'Test:_Preconfigured_Index_Record',
|
||||
referencedByCount: 0,
|
||||
referenced_by_count: 0,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe('legacy', () => {
|
||||
it('should handle get all action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/actions`).expect(200, [
|
||||
{
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
referencedByCount: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured-es-index-action',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.index',
|
||||
name: 'preconfigured_es_index_action',
|
||||
referencedByCount: 0,
|
||||
},
|
||||
{
|
||||
id: 'my-slack1',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: '.slack',
|
||||
name: 'Slack#xyz',
|
||||
referencedByCount: 0,
|
||||
},
|
||||
{
|
||||
id: 'custom-system-abc-connector',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'system-abc-action-type',
|
||||
name: 'SystemABC',
|
||||
referencedByCount: 0,
|
||||
},
|
||||
{
|
||||
id: 'preconfigured.test.index-record',
|
||||
isPreconfigured: true,
|
||||
actionTypeId: 'test.index-record',
|
||||
name: 'Test:_Preconfigured_Index_Record',
|
||||
referencedByCount: 0,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ export default function actionsTests({ loadTestFile, getService }: FtrProviderCo
|
|||
loadTestFile(require.resolve('./delete'));
|
||||
loadTestFile(require.resolve('./get_all'));
|
||||
loadTestFile(require.resolve('./get'));
|
||||
loadTestFile(require.resolve('./list_action_types'));
|
||||
loadTestFile(require.resolve('./connector_types'));
|
||||
loadTestFile(require.resolve('./update'));
|
||||
loadTestFile(require.resolve('./execute'));
|
||||
loadTestFile(require.resolve('./builtin_action_types/es_index'));
|
||||
|
|
|
@ -21,11 +21,11 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should handle update action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -37,7 +37,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}`)
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action updated',
|
||||
|
@ -50,8 +50,8 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
})
|
||||
.expect(200, {
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
actionTypeId: 'test.index-record',
|
||||
is_preconfigured: false,
|
||||
connector_type_id: 'test.index-record',
|
||||
name: 'My action updated',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
|
@ -69,11 +69,11 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't update action from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
|
@ -105,7 +105,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it(`shouldn't update action from preconfigured list`, async () => {
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/custom-system-abc-connector`)
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/custom-system-abc-connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action updated',
|
||||
|
@ -125,11 +125,11 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should notify feature usage when editing a gold action type', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'Noop action type',
|
||||
actionTypeId: 'test.noop',
|
||||
connector_type_id: 'test.noop',
|
||||
secrets: {},
|
||||
config: {},
|
||||
})
|
||||
|
@ -138,7 +138,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
|
||||
const updateStart = new Date();
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}`)
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'Noop action type updated',
|
||||
|
@ -158,5 +158,147 @@ export default function updateActionTests({ getService }: FtrProviderContext) {
|
|||
expect(noopFeature.last_used).to.be.a('string');
|
||||
expect(new Date(noopFeature.last_used).getTime()).to.be.greaterThan(updateStart.getTime());
|
||||
});
|
||||
|
||||
describe('legacy', () => {
|
||||
it('should handle update action request appropriately', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action updated',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200, {
|
||||
id: createdAction.id,
|
||||
isPreconfigured: false,
|
||||
actionTypeId: 'test.index-record',
|
||||
name: 'My action updated',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
});
|
||||
|
||||
// Ensure AAD isn't broken
|
||||
await checkAAD({
|
||||
supertest,
|
||||
spaceId: Spaces.space1.id,
|
||||
type: 'action',
|
||||
id: createdAction.id,
|
||||
});
|
||||
});
|
||||
|
||||
it(`shouldn't update action from another space`, async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action',
|
||||
actionTypeId: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(Spaces.other.id)}/api/actions/action/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action updated',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
message: `Saved object [action/${createdAction.id}] not found`,
|
||||
});
|
||||
});
|
||||
|
||||
it(`shouldn't update action from preconfigured list`, async () => {
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/custom-system-abc-connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My action updated',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(400, {
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: `Preconfigured action custom-system-abc-connector is not allowed to update.`,
|
||||
});
|
||||
});
|
||||
|
||||
it('should notify feature usage when editing a gold action type', async () => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'Noop action type',
|
||||
actionTypeId: 'test.noop',
|
||||
secrets: {},
|
||||
config: {},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const updateStart = new Date();
|
||||
await supertest
|
||||
.put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/${createdAction.id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'Noop action type updated',
|
||||
secrets: {},
|
||||
config: {},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
const {
|
||||
body: { features },
|
||||
} = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/licensing/feature_usage`);
|
||||
expect(features).to.be.an(Array);
|
||||
const noopFeature = features.find(
|
||||
(feature: { name: string }) => feature.name === 'Connector: Test: Noop'
|
||||
);
|
||||
expect(noopFeature).to.be.ok();
|
||||
expect(noopFeature.last_used).to.be.a('string');
|
||||
expect(new Date(noopFeature.last_used).getTime()).to.be.greaterThan(updateStart.getTime());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue