stackstorm 11. Webhooks

1 Webhooks


Webhooks允许通过使用HTTP webhooks集成外部系统到StackStorm中。
不像传感器sensor使用的pull方法,webhooks使用了一个push方法。
它们通过使用HTTP Post请求将触发器trigger直接推到StackStorm的API中。

2 Sensors和Webhooks


传感器集成到外部系统并且,服务使用了一种polling方法(传感器周期性地连接到
外部系统来键所数据),或者一个被动的方法,它们监听某个端口,使用
你定义的协议来接受数据。

Webhooks提供了内置的被动方法来用于接受JSON或者URL编码格式的数据,
通过HTTP POST。当一个感兴趣的事件发生的时候,
这个数据必须被外部系统push到StackStorm中。

Sensores则是预先设定集成方法,因为它们提供了一个更细粒度的和紧密的集成。

从另一方面说,webhooks很容易进入,当你有一个已经存在的脚本或者软件,该脚本或软件可以很容易地修改
未发送一个webhook到StackStorm的API中当一个感兴趣的事件发生时。

另一个webhooks又用的例子时当你想要从一个已经提供了webhook集成的第三方服务来消费事件的时候,
例如GitHub。

3 验证


所有的请求被发送到 /api/v1/webhooks 端点上,请求需要被验证,正如其他
API请求一样。有两种可能的校验方法--API键和令牌。
https://docs.stackstorm.com/authentication.html#authentication-apikeys
API键被 对键用于webhooks中,正如它们不会过期一样。
另派有一个固定的故其事件。

3.1 基于API键


Header: St2-Api-Key
查询参数: ?st2-api-key

3.2 基于令牌


Header: X-Auth-Token
查询参数: ?x-auth-token

上面两种方式都支持提供校验材料作为header或者查询参数。
一个header通常配用于你的脚本,该脚本中你可以控制请求的头部,而
查询参数被用于第三方库服务,例如GitHub或者你可以指定一个URL。

4 请求体


request body或者叫做trigger payload可以以JSOn或者URL编码格式的数据。
body类型被基于 Content-Type的类型所决定(application/json用于json,并且
application/x-www-form-urlencoded 用于URL编码格式的数据)。
所有的样例假设JSON提供了一个application/json用于Content-Type头部值。

5 注册一个Webhook


你可以通过在StackStorm中指定一个规则定义内部的core.st2.webhook的触发器来
注册一个webhook。

下面是一个来自规则中注册一个新的名叫webhook的摘录内容:
...
trigger:
        type: "core.st2.webhook"
        parameters:
            url: "sample"
...

上述这个 url: 参数会被添加到/api/v1/webhooks/的后面作为后缀来创建一个
URL来提交数据。因此,一旦你已经创建了上述的规则,你可以通过提交数据到
StackStorm服务的
https://{$ST2_IP}/api/v1/webhooks/sample
地址来使用这个webhook。

请求体必须是JSON格式,并且可能包含任意你可能用于匹配规则标准的数据。

注意url参数中所有的拖尾的和首位的/都会被StackStorm忽律。
例如: /sample, sample/, /sample/ 和 sample 都会被认为是相同的。
它们会产生一个有效的url: 
/api/v1/webhooks/sample

POST-ing 数据到一个定制的webhook将会引起携带有如下属性的触发器被
迅速处理:

trigger - 触发器名称。
trigger.headers - 包含请求头部的字典
trigger.body - 包含有请求体的字典

这个例子显示了如何通过curl发送数据到一个定制化的webhook
来匹配规则标准:


curl -X POST https://localhost/api/v1/webhooks/sample -H "X-Auth-Token: matoken" -H "Content-Type: application/json" --data '{"key1": "value1"}'

规则:

...
trigger:
        type: "core.st2.webhook"
        parameters:
            url: "sample"

criteria:
    trigger.body.key1:
        type: "equals"
        pattern: "value1"

action:
    ref: "mypack.myaction"
    parameters:
...


6 使用一个通用的Webhook


默认地,一个拥有st2名字的特殊目的的webhook已经被注册了。
它允许你指定任何StackStorm已知的触发器而非使用 core,.st2.webhook
(要么是默认的,要么是来自于packs中的定制化的传感器和触发器),元年赐你可以
使用它来触发哪些不是明确被webhooks触发的规则。

请求体必须是JSON并且包含下面的属性:
trigger : 触发器的名称(例如: mypack.mytrigger)
payload : 一个触发器payload对象

这个例子显示了如何使用curl发送数据到通用的webhook,
并且如何匹配那些使用了规则标准的数据(如果你是调用远程的url,请用你的StackStorm的host来替代
localhost)

curl -X POST https://localhost/api/v1/webhooks/st2 -H "X-Auth-Token: matoken" -H "Content-Type: application/json" --data '{"trigger": "mypack.mytrigger", "payload": {"attribute1": "value1"}}'

规则:
...
trigger:
    type: "mypack.mytrigger"

criteria:
    trigger.attribute1:
        type: "equals"
        pattern: "value1"

action:
    ref: "mypack.myaction"
    parameters:
...

这个在规则定义中的trigger.type属性需要和
定义在webhook的payload体中的trigger名称一致。


7 列出注册的Webhooks


为了列出所有已经注册的webhooks,运行:
st2 webhook list

8 我的Webhook不工作


遇到问题请参阅:
https://docs.stackstorm.com/troubleshooting/webhooks.html

9 什么时候不要使用Webhooks


尽管webhooks有用,但是它们有两个缺点:
1) 非双向的: Webhooks仅仅提交数据到StackStorm中。因此如果你想要从
StackStorm获取返回的数据,或者一个动作的执行id,你需要以异步方式
来获取数据。

2) 不保证执行: StackStorm中的Webhooks布保证一次执行。它依赖于规则配置文件。
基于webhook内容,它可能不会执行任何动作,或者可能执行多个动作。

如果你想要执行一个特定的动作或者工作流,或者你希望得到有保证的响应,你可以使用
/v1/executions API。这和通过命令行 st2 run <mypack>.<myaction>来明确运行一个动作
是相同的。

我们可以知道如何使用--debug标记:

st2 --debug run core.local "date"
2017-03-31 08:21:18,706  DEBUG - Using cached token from file "/home/ubuntu/.st2/token-st2admin"
# -------- begin 140183979680208 request ----------
curl -X GET -H  'Connection: keep-alive' -H  'Accept-Encoding: gzip, deflate' -H  'Accept: */*' -H  'User-Agent: python-requests/2.11.1' -H  'X-Auth-Token: da5ecf3b0ab841008d663052fe95cddd' http://127.0.0.1:9101/v1/actions/core.local
# -------- begin 140183979680208 response ----------
{"name": "local", "parameters": {"cmd": {"required": true, "type": "string", "description": "Arbitrary Linux command to be executed on the local host."}, "sudo": {"immutable": true}}, "tags": [], "description": "Action that executes an arbitrary Linux command on the localhost.", "enabled": true, "entry_point": "", "notify": {}, "uid": "action:core:local", "pack": "core", "ref": "core.local", "id": "58c9663a49d4af4cbd56f84d", "runner_type": "local-shell-cmd"}
# -------- end 140183979680208 response ------------

# -------- begin 140183979680080 request ----------
curl -X GET -H  'Connection: keep-alive' -H  'Accept-Encoding: gzip, deflate' -H  'Accept: */*' -H  'User-Agent: python-requests/2.11.1' -H  'X-Auth-Token: da5ecf3b0ab841008d663052fe95cddd' 'http://127.0.0.1:9101/v1/runnertypes/?name=local-shell-cmd'
# -------- begin 140183979680080 response ----------
[{"runner_module": "local_runner", "uid": "runner_type:local-shell-cmd", "description": "A runner to execute local actions as a fixed user.", "enabled": true, "runner_parameters": {"sudo": {"default": false, "type": "boolean", "description": "The command will be executed with sudo."}, "timeout": {"default": 60, "type": "integer", "description": "Action timeout in seconds. Action will get killed if it doesn't finish in timeout seconds."}, "cmd": {"type": "string", "description": "Arbitrary Linux command to be executed on the host."}, "kwarg_op": {"default": "--", "type": "string", "description": "Operator to use in front of keyword args i.e. \"--\" or \"-\"."}, "env": {"type": "object", "description": "Environment variables which will be available to the command(e.g. key1=val1,key2=val2)"}, "cwd": {"type": "string", "description": "Working directory where the command will be executed in"}}, "id": "58c9663a49d4af4cbd56f847", "name": "local-shell-cmd"}]
# -------- end 140183979680080 response ------------

# -------- begin 140183979680976 request ----------
curl -X POST -H  'Connection: keep-alive' -H  'Accept-Encoding: gzip, deflate' -H  'Accept: */*' -H  'User-Agent: python-requests/2.11.1' -H  'content-type: application/json' -H  'X-Auth-Token: da5ecf3b0ab841008d663052fe95cddd' -H  'Content-Length: 69' --data-binary '{"action": "core.local", "user": null, "parameters": {"cmd": "date"}}' http://127.0.0.1:9101/v1/executions
# -------- begin 140183979680976 response ----------
{"status": "requested", "start_timestamp": "2017-03-31T08:21:18.828620Z", "log": [{"status": "requested", "timestamp": "2017-03-31T08:21:18.843043Z"}], "parameters": {"cmd": "date"}, "runner": {"runner_module": "local_runner", "uid": "runner_type:local-shell-cmd", "description": "A runner to execute local actions as a fixed user.", "enabled": true, "runner_parameters": {"sudo": {"default": false, "type": "boolean", "description": "The command will be executed with sudo."}, "timeout": {"default": 60, "type": "integer", "description": "Action timeout in seconds. Action will get killed if it doesn't finish in timeout seconds."}, "cmd": {"type": "string", "description": "Arbitrary Linux command to be executed on the host."}, "kwarg_op": {"default": "--", "type": "string", "description": "Operator to use in front of keyword args i.e. \"--\" or \"-\"."}, "env": {"type": "object", "description": "Environment variables which will be available to the command(e.g. key1=val1,key2=val2)"}, "cwd": {"type": "string", "description": "Working directory where the command will be executed in"}}, "id": "58c9663a49d4af4cbd56f847", "name": "local-shell-cmd"}, "web_url": "https://st2expect/#/history/58de117e49d4af083399181c/general", "context": {"user": "st2admin"}, "action": {"description": "Action that executes an arbitrary Linux command on the localhost.", "runner_type": "local-shell-cmd", "tags": [], "enabled": true, "pack": "core", "entry_point": "", "notify": {}, "uid": "action:core:local", "parameters": {"cmd": {"required": true, "type": "string", "description": "Arbitrary Linux command to be executed on the local host."}, "sudo": {"immutable": true}}, "ref": "core.local", "id": "58c9663a49d4af4cbd56f84d", "name": "local"}, "liveaction": {"runner_info": {}, "parameters": {"cmd": "date"}, "action_is_workflow": false, "callback": {}, "action": "core.local", "id": "58de117e49d4af083399181b"}, "id": "58de117e49d4af083399181c"}
# -------- end 140183979680976 response ------------

# -------- begin 140183979680976 request ----------
curl -X GET -H  'Connection: keep-alive' -H  'Accept-Encoding: gzip, deflate' -H  'Accept: */*' -H  'User-Agent: python-requests/2.11.1' -H  'X-Auth-Token: da5ecf3b0ab841008d663052fe95cddd' http://127.0.0.1:9101/v1/executions/58de117e49d4af083399181c
# -------- begin 140183979680976 response ----------
{"status": "succeeded", "start_timestamp": "2017-03-31T08:21:18.828620Z", "log": [{"status": "requested", "timestamp": "2017-03-31T08:21:18.843000Z"}, {"status": "scheduled", "timestamp": "2017-03-31T08:21:18.943000Z"}, {"status": "running", "timestamp": "2017-03-31T08:21:19.041000Z"}, {"status": "succeeded", "timestamp": "2017-03-31T08:21:19.242000Z"}], "parameters": {"cmd": "date"}, "runner": {"runner_module": "local_runner", "uid": "runner_type:local-shell-cmd", "enabled": true, "name": "local-shell-cmd", "runner_parameters": {"sudo": {"default": false, "type": "boolean", "description": "The command will be executed with sudo."}, "timeout": {"default": 60, "type": "integer", "description": "Action timeout in seconds. Action will get killed if it doesn't finish in timeout seconds."}, "cmd": {"type": "string", "description": "Arbitrary Linux command to be executed on the host."}, "kwarg_op": {"default": "--", "type": "string", "description": "Operator to use in front of keyword args i.e. \"--\" or \"-\"."}, "env": {"type": "object", "description": "Environment variables which will be available to the command(e.g. key1=val1,key2=val2)"}, "cwd": {"type": "string", "description": "Working directory where the command will be executed in"}}, "id": "58c9663a49d4af4cbd56f847", "description": "A runner to execute local actions as a fixed user."}, "elapsed_seconds": 0.378813, "web_url": "https://st2expect/#/history/58de117e49d4af083399181c/general", "result": {"failed": false, "stderr": "", "return_code": 0, "succeeded": true, "stdout": "Fri Mar 31 08:21:19 UTC 2017"}, "context": {"user": "st2admin"}, "action": {"runner_type": "local-shell-cmd", "name": "local", "parameters": {"cmd": {"required": true, "type": "string", "description": "Arbitrary Linux command to be executed on the local host."}, "sudo": {"immutable": true}}, "tags": [], "enabled": true, "entry_point": "", "notify": {}, "uid": "action:core:local", "pack": "core", "ref": "core.local", "id": "58c9663a49d4af4cbd56f84d", "description": "Action that executes an arbitrary Linux command on the localhost."}, "liveaction": {"runner_info": {"hostname": "st2expect", "pid": 1657}, "parameters": {"cmd": "date"}, "action_is_workflow": false, "callback": {}, "action": "core.local", "id": "58de117e49d4af083399181b"}, "id": "58de117e49d4af083399181c", "end_timestamp": "2017-03-31T08:21:19.207433Z"}
# -------- end 140183979680976 response -----------

id: 58de117e49d4af083399181c
status: succeeded
parameters:
  cmd: date
result:
  failed: false
  return_code: 0
  stderr: ''
  stdout: Fri Mar 31 08:21:19 UTC 2017
  succeeded: true

除了通常的输出显示了执行的结果外, --debug标记也显示了API调用过程中
整个的交互,是以curl命令的格式显示的。

这个输出显示了当执行StackStorm宿主机上的命令时API调用的信息。
如果你正从一个远程系统访问API,它将通过nginx代理,使用/api的URI。
因此远程调用将会采用如下形式:

curl -X POST https://[ST2_IP]/api/v1/executions -H  'Connection: keep-alive' -H  'Accept-Encoding: gzip, deflate' -H  'Accept: */*' -H  'User-Agent: python-requests/2.11.1' -H  'content-type: application/json' -H  'X-Auth-Token: matoken' -H  'Content-Length: 69' --data-binary '{"action": "core.local", "user": null, "parameters": {"cmd": "date"}}'


以上翻译自:
https://docs.stackstorm.com/webhooks.html

猜你喜欢

转载自blog.csdn.net/qingyuanluofeng/article/details/86585351