onwebhook.adoc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. [#exec-webhook]
  2. = Execute on webhook
  3. Webhooks allow external services to trigger OliveTin actions by sending HTTP POST requests. This is useful for integrating OliveTin with CI/CD pipelines, monitoring systems, IoT devices, or any service that can send HTTP requests.
  4. OliveTin provides a dedicated webhook endpoint at `/webhooks` that can receive webhook payloads and match them to configured actions.
  5. == Basic Configuration
  6. To configure an action to run on a webhook, add the `execOnWebhook` property to your action. Webhook-triggered actions **must** use `exec:` (not `shell:` or `shellAfterCompleted`).
  7. [source,yaml]
  8. .`config.yaml`
  9. ----
  10. actions:
  11. - title: Deploy Application
  12. id: deploy
  13. exec:
  14. - /opt/scripts/deploy.sh
  15. execOnWebhook:
  16. - matchHeaders:
  17. X-Event-Type: deploy
  18. ----
  19. This action will be triggered when a POST request is sent to `/webhooks` with the header `X-Event-Type: deploy`.
  20. == Webhook Endpoint
  21. All webhooks are received at:
  22. ----
  23. http://your-olivetin-server:1337/webhooks
  24. ----
  25. or
  26. ----
  27. http://your-olivetin-server:1337/webhooks/
  28. ----
  29. Both paths work identically. All webhook requests must use the HTTP POST method.
  30. == Matching Webhooks
  31. OliveTin can match incoming webhooks based on several criteria:
  32. === Match by Headers
  33. Match webhooks based on HTTP header values:
  34. [source,yaml]
  35. ----
  36. actions:
  37. - title: Process Event
  38. exec:
  39. - echo
  40. - "Processing event"
  41. execOnWebhook:
  42. - matchHeaders:
  43. X-Event-Type: my-event
  44. X-Source: my-service
  45. ----
  46. All specified headers must match for the webhook to trigger the action.
  47. === Match by Query Parameters
  48. Match webhooks based on URL query parameters:
  49. [source,yaml]
  50. ----
  51. actions:
  52. - title: Process Request
  53. exec:
  54. - echo
  55. - "Processing request for {{ service }}"
  56. arguments:
  57. - name: service
  58. type: ascii
  59. execOnWebhook:
  60. - matchQuery:
  61. action: deploy
  62. env: production
  63. extract:
  64. service: "$.service"
  65. ----
  66. A request to `/webhooks?action=deploy&env=production` with a JSON body containing `"service"` would match this action and pass that field into the `service` argument.
  67. === Match by JSON Body Path
  68. Match webhooks based on values in the JSON request body using JSONPath expressions:
  69. [source,yaml]
  70. ----
  71. actions:
  72. - title: Handle Push Event
  73. exec:
  74. - echo
  75. - "Push to {{ branch }}"
  76. arguments:
  77. - name: branch
  78. type: ascii
  79. execOnWebhook:
  80. - matchPath: "$.event_type=push"
  81. extract:
  82. branch: "$.branch"
  83. ----
  84. The `matchPath` format is `jsonpath=value`. You can also just specify a JSONPath without a value to match if the path exists:
  85. [source,yaml]
  86. ----
  87. execOnWebhook:
  88. - matchPath: "$.repository.name" # Matches if this path exists in the JSON
  89. ----
  90. === Using Regex for Matching
  91. Header and query parameter values can use regex patterns by prefixing with `regex:`:
  92. [source,yaml]
  93. ----
  94. actions:
  95. - title: Handle Multiple Events
  96. exec:
  97. - echo
  98. - "Handling event"
  99. execOnWebhook:
  100. - matchHeaders:
  101. X-Event-Type: "regex:^(push|pull_request|release)$"
  102. ----
  103. === Combining Match Criteria
  104. You can combine multiple match criteria. All criteria must match for the webhook to trigger:
  105. [source,yaml]
  106. ----
  107. actions:
  108. - title: Production Deploy
  109. exec:
  110. - /opt/scripts/deploy.sh
  111. - production
  112. execOnWebhook:
  113. - matchHeaders:
  114. X-Event-Type: deploy
  115. matchQuery:
  116. environment: production
  117. matchPath: "$.status=approved"
  118. ----
  119. == Extracting Arguments from Webhooks
  120. You can extract values from the webhook payload and pass them as arguments to your action using JSONPath expressions:
  121. [source,yaml]
  122. ----
  123. actions:
  124. - title: Deploy Version
  125. exec:
  126. - /opt/scripts/deploy.sh
  127. - "{{ version }}"
  128. - "{{ environment }}"
  129. arguments:
  130. - name: version
  131. type: ascii
  132. - name: environment
  133. type: ascii
  134. execOnWebhook:
  135. - matchHeaders:
  136. X-Event-Type: deploy
  137. extract:
  138. version: "$.release.tag_name"
  139. environment: "$.target.environment"
  140. ----
  141. The `extract` map defines which action arguments to populate from the webhook payload. The key is the argument name, and the value is the JSONPath expression to extract the value.
  142. === Automatic Webhook Metadata
  143. OliveTin automatically adds several metadata arguments from each webhook request:
  144. * `webhook_method` - The HTTP method (always POST for webhooks)
  145. * `webhook_path` - The request URL path
  146. * `webhook_query` - The raw query string
  147. * `webhook_header_<name>` - Each HTTP header (lowercase name)
  148. For example, to access the `X-Request-Id` header in your action:
  149. [source,yaml]
  150. ----
  151. actions:
  152. - title: Log Request
  153. exec:
  154. - echo
  155. - 'Request ID: {{ index .Arguments "webhook_header_x-request-id" }}'
  156. arguments:
  157. - name: webhook_header_x-request-id
  158. type: ascii
  159. execOnWebhook:
  160. - matchHeaders:
  161. X-Event-Type: log
  162. ----
  163. Header names that contain hyphens become argument keys with the same hyphens (for example `webhook_header_x-request-id`). Use the `index` map-lookup form shown above, because Go templates treat hyphens in bare identifiers as subtraction.
  164. == Webhook Authentication
  165. OliveTin supports several authentication methods to verify webhook requests:
  166. === No Authentication
  167. By default, webhooks have no authentication. Any request matching the criteria will trigger the action:
  168. [source,yaml]
  169. ----
  170. execOnWebhook:
  171. - authType: none
  172. matchHeaders:
  173. X-Event-Type: my-event
  174. ----
  175. === HMAC-SHA256 Signature
  176. Verify webhooks using HMAC-SHA256 signatures (commonly used by GitHub, GitLab, etc.):
  177. [source,yaml]
  178. ----
  179. execOnWebhook:
  180. - authType: hmac-sha256
  181. authHeader: X-Hub-Signature-256
  182. secret: your-webhook-secret
  183. matchHeaders:
  184. X-Event-Type: push
  185. ----
  186. The `authHeader` specifies which header contains the signature. The signature should be in the format `sha256=<hex-encoded-signature>`.
  187. === HMAC-SHA1 Signature
  188. For services using HMAC-SHA1 (legacy GitHub webhooks):
  189. [source,yaml]
  190. ----
  191. execOnWebhook:
  192. - authType: hmac-sha1
  193. authHeader: X-Hub-Signature
  194. secret: your-webhook-secret
  195. matchHeaders:
  196. X-Event-Type: push
  197. ----
  198. === Bearer Token
  199. Verify webhooks using a Bearer token in the Authorization header:
  200. [source,yaml]
  201. ----
  202. execOnWebhook:
  203. - authType: bearer
  204. secret: your-bearer-token
  205. matchHeaders:
  206. X-Event-Type: deploy
  207. ----
  208. The webhook sender must include `Authorization: Bearer your-bearer-token` in the request.
  209. === Basic Authentication
  210. Verify webhooks using HTTP Basic authentication:
  211. [source,yaml]
  212. ----
  213. execOnWebhook:
  214. - authType: basic
  215. secret: "username:password"
  216. matchHeaders:
  217. X-Event-Type: deploy
  218. ----
  219. Or with password only:
  220. [source,yaml]
  221. ----
  222. execOnWebhook:
  223. - authType: basic
  224. secret: "mypassword"
  225. matchHeaders:
  226. X-Event-Type: deploy
  227. ----
  228. == Multiple Webhook Triggers
  229. An action can have multiple webhook configurations. The action will be triggered if any of them match:
  230. [source,yaml]
  231. ----
  232. actions:
  233. - title: Deploy
  234. exec:
  235. - /opt/scripts/deploy.sh
  236. execOnWebhook:
  237. - matchHeaders:
  238. X-Event-Type: deploy-manual
  239. - matchHeaders:
  240. X-Event-Type: deploy-auto
  241. matchPath: "$.status=success"
  242. ----
  243. == Testing Webhooks
  244. You can test your webhook configuration using `curl`:
  245. [source,bash]
  246. ----
  247. # Simple webhook with headers
  248. curl -X POST \
  249. -H "Content-Type: application/json" \
  250. -H "X-Event-Type: deploy" \
  251. -d '{"version": "1.2.3"}' \
  252. http://localhost:1337/webhooks
  253. # Webhook with HMAC-SHA256 authentication
  254. SECRET="your-secret"
  255. PAYLOAD='{"event": "push", "branch": "main"}'
  256. SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2)
  257. curl -X POST \
  258. -H "Content-Type: application/json" \
  259. -H "X-Event-Type: push" \
  260. -H "X-Hub-Signature-256: sha256=$SIGNATURE" \
  261. -d "$PAYLOAD" \
  262. http://localhost:1337/webhooks
  263. ----
  264. == See Also
  265. * xref:action_execution/onwebhook_github.adoc[GitHub Webhooks] - Specific configuration for GitHub webhook events
  266. * xref:solutions/on-git-push/index.adoc[GitOps Solution] - Running actions on Git push using hooks
  267. * xref:api/start_action.adoc[Start Action API] - Alternative method for triggering actions via API