Contents
Webhookを受けるツールを作ろうと思っていたところGo製のwebhookがあったので、使ってみました。
webhook
ドキュメント
検証環境
項目 | バージョン |
---|---|
CentOS | 7.7.1908 |
インストール
ビルド済みのバイナリがダウンロードできるので、今回はそちらを使います。
1 2 |
[root@Wehook01 ~]# curl -L https://github.com/adnanh/webhook/releases/download/2.6.10/webhook-linux-amd64.tar.gz -O |
ダウンロードしたら解凍します。
1 2 3 4 5 |
[root@Wehook01 ~]# tar zxvf webhook-linux-amd64.tar.gz [root@Wehook01 ~]# cd webhook-linux-amd64 [root@Wehook01 webhook-linux-amd64]# ls webhook |
検証
以下のシェルスクリプトを作って、webhookから実行してみようと思います。
1 2 |
[root@Wehook01 webhook-linux-amd64]# vi /opt/test.sh |
1 2 3 4 5 |
#!/bin/bash echo $1 >> /opt/r.txt echo $2 >> /opt/r.txt |
webhookからコマンドの実行
webhookの設定ファイルはjsonで作成します。
次の設定はwebhookでリクエストを受け取った場合、スクリプトを実行します。
1 2 |
[root@Wehook01 webhook-linux-amd64]# vi hooks.json |
1 2 3 4 5 6 7 8 |
[ { "id": "webhook", "execute-command": "/opt/test.sh", "command-working-directory": "/opt" } ] |
設定ファイル作成後にwebhookを起動します。
1 2 3 4 5 6 7 8 9 |
[root@Wehook01 webhook-linux-amd64]# ./webhook -hooks hooks.json -verbose [webhook] 2019/10/14 14:50:26 version 2.6.10 starting [webhook] 2019/10/14 14:50:26 setting up os signal watcher [webhook] 2019/10/14 14:50:26 attempting to load hooks from hooks.json [webhook] 2019/10/14 14:50:26 found 1 hook(s) in file [webhook] 2019/10/14 14:50:26 loaded: webhook [webhook] 2019/10/14 14:50:26 os signal watcher ready [webhook] 2019/10/14 14:50:26 serving hooks on http://0.0.0.0:9000/hooks/{id} |
curlでwebhookにアクセスしてみます。
アクセスするアドレスは以下の通りです。
1 2 |
http://webhookserver ip or fqdn:9000/hooks/{id} |
デフォルトはポート 9000
です。
{id}
は、設定ファイルのJSONで定義したidです。
実際にアクセスするアドレスは以下のようになります。
1 2 |
[root@206d9746e86c /]# curl http://192.168.0.122:9000/hooks/webhook |
ファイルが作成されているか確認します。
リクエストは「空」なので、空ファイルが作成されていることを確認します。
1 2 3 4 |
[root@Wehook01 opt]# cat r.txt |
webhookからのコマンドに引数を渡す
次にwebhookから受け取ったパラメーターをコマンドの引数に渡してみます。
引数は以下のパラメーターで指定できます。
パラメーター | 説明 |
---|---|
header | HTTPリクエストヘッダー |
url | HTTPクエリーパラメーター |
payload | リクエストJSON |
HTTPヘッダー
HTTPヘッダーの場合は、以下のように設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[ { "id": "webhook", "execute-command": "/opt/test.sh", "command-working-directory": "/opt", "pass-arguments-to-command": [ { "source": "header", "name": "Header1" }, { "source": "header", "name": "Header2" }, ] } ] |
curlでヘッダーを指定してwebhookへアクセスします。
1 2 |
[root@206d9746e86c /]# curl -H "Header1:header1" -H "Header2:header2" http://192.168.0.122:9000/hooks/webhook |
HTTPヘッダーがシェルスクリプトに引数で渡されたか確認します。
1 2 3 4 |
[root@Wehook01 opt]# cat r.txt header1 header2 |
URLクエリー
URLクエリーの場合は、以下のように設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[ { "id": "webhook", "execute-command": "/opt/test.sh", "command-working-directory": "/opt", "pass-arguments-to-command": [ { "source": "url", "name": "header1" }, { "source": "url", "name": "header2" }, ] } ] |
curlでクエリーを指定してwebhookへアクセスします。
1 2 |
[root@206d9746e86c /]# curl 'http://192.168.0.122:9000/hooks/webhook?header1=header1&header2=header2' |
URLクエリーがシェルスクリプトに引数で渡されたか確認します。
1 2 3 4 |
[root@Wehook01 opt]# cat r.txt header1 header2 |
JSON
JSONの場合は、以下のように設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[ { "id": "webhook", "execute-command": "/opt/test.sh", "command-working-directory": "/opt", "pass-arguments-to-command": [ { "source": "payload", "name": "header1" }, { "source": "payload", "name": "data.header2" }, ] } ] |
curlでJSONを指定してwebhookへアクセスします。
1 2 |
[root@206d9746e86c /]# curl -X POST -H "Content-Type: application/json" -d '{"header1":"header1","data":{"header2":"header2"}}' http://192.168.0.122:9000/hooks/webhook |
JSONのデータがシェルスクリプトに引数で渡されたか確認します。
1 2 3 4 |
[root@Wehook01 opt]# cat r.txt header1 header2 |
条件指定
webhookで受け取ったパラメーターを元に条件を指定してスクリプトの実行を制御することができます。
条件は and
or
not
が使えます。
ここでは and
を例に使ってみようと思います。
以下の条件では CMDEXEC
ヘッダーの値が True
であればコマンドを実行するというand条件を追加しています。
ちなみに match
で指定できるタイプは value
regex
payload-hash-sha1
ip-whitelist
scalr-signature
などがあります。
詳細はドキュメントを確認してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
[ { "id": "webhook", "execute-command": "/opt/test.sh", "command-working-directory": "/opt", "pass-arguments-to-command": [ { "source": "payload", "name": "header1" }, { "source": "payload", "name": "data.header2" }, ], "trigger-rule": { "and": [ { "match": { "type": "value", "value": "True", "parameter": { "source": "header", "name": "CMDEXEC" } } } ] } } ] |
curlでヘッダーにTrueおよびJSONを指定してwebhookへアクセスします。
1 2 |
[root@206d9746e86c /]# curl -X POST -H "CMDEXEC: True" -H "Content-Type: application/json" -d '{"header1":"header1","data":{"header2":"header2"}}' http://192.168.0.122:9000/hooks/webhook |
JSONのデータがシェルスクリプトに引数で渡されたか確認します。
1 2 3 4 |
[root@Wehook01 opt]# cat r.txt header1 header2 |
次にヘッダーにTrue以外の文字列を指定してwebhookへアクセスします。
1 2 3 |
[root@206d9746e86c /]# curl -X POST -H "CMDEXEC: False" -H "Content-Type: application/json" -d '{"header1":"header1","data":{"header2":"header2"}}' http://192.168.0.122:9000/hooks/webhook Hook rules were not satisfied. |
このように条件が満たされない場合はメッセージが表示されます。
最後に
webhook経由でコマンドを実行したい場合は、このwebhookを使う事で簡単に実装できそうですね。
Goで出来ているのでWindows/Linux/Macでも動くので、基本どこでも使えますね 🙂
色々なツールと組み合わせる事でCI/CD基盤でも有効に使えそうです。