Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event hooks #171

Merged
merged 41 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0361f32
event hooks docs
Guaris Dec 11, 2024
1f47364
fix example
Guaris Dec 11, 2024
f60cdb9
fix mermaid
Guaris Dec 12, 2024
71c92e5
add api spec
Guaris Dec 12, 2024
bac7100
sources.yml
Guaris Dec 12, 2024
f67efe5
mermaid
Guaris Dec 13, 2024
c89bb20
updates
Guaris Dec 13, 2024
34d6b09
event hooks tested and done
Guaris Dec 16, 2024
0b9cea6
vale and consistency
Guaris Dec 16, 2024
6b0fe1f
last vale
Guaris Dec 16, 2024
db9f57c
Add ee_product_name
fabianrbz Dec 18, 2024
5810551
Make `products` a required for how_tos
fabianrbz Dec 18, 2024
e45a0d1
Add missing `products` to how-to
fabianrbz Dec 18, 2024
6196aa2
Fabian changes
Guaris Dec 19, 2024
446e682
Fix broken include and warning
fabianrbz Dec 19, 2024
566f89b
Fix entitities' page layout
fabianrbz Dec 19, 2024
280a0ef
Minor style fixes
fabianrbz Dec 19, 2024
54514a0
KIC and Terraform don't support event-hooks
fabianrbz Dec 19, 2024
84d4dff
Creating event hooks is not possible in the ui
fabianrbz Dec 19, 2024
c29920d
Add `Setup an Event Hook` section
fabianrbz Dec 19, 2024
19fd4f0
Vale fixes
fabianrbz Dec 19, 2024
40722dd
Use same tags in eventhooks how-tos
fabianrbz Dec 19, 2024
729b890
Add terms to the Dictionary and keys to ignore in Frontmatters
fabianrbz Dec 19, 2024
6dd7143
More Vale fixes
fabianrbz Dec 19, 2024
321715b
Fix path to event-hooks schema
fabianrbz Dec 19, 2024
cca6771
fix-feedback
Guaris Dec 19, 2024
a348eb9
rename
Guaris Dec 19, 2024
ac5349d
vale
Guaris Dec 19, 2024
021f9cb
Update create-a-webhook-with-kong-gateway.md
fabianrbz Dec 19, 2024
1ac19ab
Fix event-hooks endpoint
fabianrbz Dec 19, 2024
8d0f78c
Fix code snippet
fabianrbz Dec 19, 2024
3e3b82d
Make webhook.site a link
fabianrbz Dec 19, 2024
97636e7
Fix env variable assignment
fabianrbz Dec 19, 2024
d34d54f
Rename event_hook.md to event-hook
fabianrbz Dec 19, 2024
064603c
Standardize the order of the prereqs
fabianrbz Dec 19, 2024
8a82019
Standardize event hooks how-tos naming
fabianrbz Dec 19, 2024
c7712da
Render the product/tools divider if there's at least one tool that
fabianrbz Dec 19, 2024
46eb0e5
Cross link event targets how-tos
fabianrbz Dec 19, 2024
3f3ae79
cross-link
Guaris Dec 19, 2024
6144aff
vale
Guaris Dec 19, 2024
f649a0c
Merge branch 'main' into event-hooks
fabianrbz Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/styles/base/Dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ enum
env
etag
etcd
event_hook
eventhooks
eventTime
failover
favicon
Expand Down Expand Up @@ -507,6 +509,7 @@ loggly
lookup
lookups
loopback
llm
lua
max_args
max_headers
Expand Down Expand Up @@ -775,4 +778,4 @@ yaml
yml
yq
zipkin
zsh
zsh
4 changes: 3 additions & 1 deletion .github/styles/docs/Frontmatter.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ prereqs
related_resources
tier
tldr
works_on
works_on
konnect_product_id
no_version
5 changes: 5 additions & 0 deletions app/_data/entity_examples/upstream/example-upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: my-upstream
paths:
- /upstreams
service:
name: example-upstreams
2 changes: 1 addition & 1 deletion app/_data/schemas/frontmatter/how_to.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
"works_on"
]
},
"required": ["tldr", "content_type", "title"]
"required": ["tldr", "content_type", "title", "products"]
}
166 changes: 166 additions & 0 deletions app/_gateway_entities/event-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
---
title: Event Hooks
content_type: reference
entities:
- event-hook
tier: enterprise
description: Event Hooks allow {{site.base_gateway}} monitor to communicate with target services or resources, notifying the target resource that an event was triggered.
related_resources:
- text: Gateway Services
url: /gateway/entities/service/
- text: Routing in {{site.base_gateway}}
url: /gateway/routing/
products:
- gateway
tools:
- admin-api
schema:
api: gateway/admin-ee
path: /schemas/Event-Hooks


---

## What is an Event Hook

An Event Hook is a {{site.base_gateway}} entity that can be configured to listen for specific events from Kong entities. An Event Hook can be configured to send information to logs, or web hooks as well as third-party applications.

## How do Event Hooks work?

{{site.base_gateway}} Event Hooks work by configuring the following three elements:

* Sources: The actions or operation that trigger the Event Hook.
* Events: The Kong entity that the Event Hook monitors for actions.
* Handlers: The mechanism that defines what action is performed when an event is triggered, like sending a webhook, logging, or executing custom code.

<!-- vale off -->
{% mermaid %}
flowchart LR
subgraph events [Kong Gateway Events]
A(<b>Gateway Service</b><br>Create<br>Delete<br>Modify)
B(<b>Admins</b><br>Create<br>Delete<br>Modify)
end

subgraph handlers [Handlers]
C(<b>Webhook</b>)
D(<b>logs</b><br>)
E(<b>webhook-custom</b>)
F(<b>Lambda</b>)
end

subgraph output [Output]
W(<b> POST to third party application</b>)
X(<b> Log to /usr/local/kong/logs/error.log</b>)
Y(<b> POST to third party application</b><br>Fully customizable)
Z(<b> Custom Code Lua code </b>)
end

A --> handlers
B --> handlers

C --> W
D --> X
E --> Y
F --> Z
{% endmermaid %}
<!-- vale on -->

### Handlers

There are four types of handlers that can be used with Event Hooks:

* **`webhook`**: Issues a `POST` request to a provided URL with the event data as a payload.
* **`log`**: Logs the event and the content of the payload as a {{site.base_gateway}} log.
* **`webhook-custom`**: Fully configurable request. Supports templating, configurable body, payload, and headers.
* **`lambda`**: This handler runs Lua code after an event is triggered.

By default, the `lambda` handler is "Sandboxed". Sandboxing means that {{site.base_gateway}} restricts the types of Lua functions that can be loaded as well as the level of access to {{site.base_gateway}} that is available for these custom functions. For example, in `sandbox` mode, a `lambda` Event Hook will not have access to global values such as `kong.configuration.pg_password`, or OS level functions like `os.execute(rm -rf /*)`, but can still run Lua code like `local foo = 1 + 1`. Removing `sandbox` requires editing the `kong.conf` value `untrusted_lua`, for more information see the [kong.conf documentation](https://docs.konghq.com/gateway/3.9.x/reference/configuration/#untrusted_lua).

### Sources

{{site.base_gateway}} offers the [`/event-hooks/sources`](/api/gateway/admin-ee/#/Event-hooks/get-event-hooks-sources) endpoint where you can see all available sources, events and fields that are available for creating Event Hook templates. Sources are the actions that trigger the Event Hook.

The response body from the endpoint describes a source that can be interpreted in the following pattern:

1. **Level 1**: The source, the action that triggers the Event Hook.
2. **Level 2**: The event, this is the {{site.base_gateway}} entity that the Event Hook listens to for events.
3. **Level 3**: The available template parameters for constructing `webhook-custom` payloads.

This is an example response body:


```json
{
"data": {
"balancer": {
"health": {
"fields": [
"upstream_id",
"ip",
"port",
"hostname",
"health"
]
}
}
}
}
```

You can apply the pattern to the response body and extract the following information:

* **source**: `balancer`
* **event**: `health`
* **handler**: `webhook-custom`

The values in the `fields` array represent the available template parameters you can use when constructing a payload.

* `upstream_id`
* `ip`
* `port`
* `hostname`
* `health`

These parameters can be used to issue notifications any time an upstream in your application is not reachable.


### Available sources

- `dao:crud`: Handles `dao:crud` clustering events.
- `balancer`: Information from the load balancer like: `upstream_id`, `ip`, `port`, `hostname`, `health`
- `ai-rate-limiting-advanced`: Run an event when a rate limit has been exceeded.
- `service-protection`: Run an event when a rate limit has been exceeded.
- `rate-limiting-advanced`: Run an event when a rate limit has been exceeded.
- `crud`: Create, read, and update events from {{site.base_gateway}} entities such as Consumers.
- `oas-validation`: Runs an event when [OAS validation Plugin](/plugins/oas-validation/) fails.

For information about specific events related to a source issue a `GET` request to the `/event-hooks/sources/{source}` endpoint. Doing so will return a list of all of the events associated to a source like: `balancer: health`.

## Schema

{% entity_schema %}

## Set up an Event Hook

{% entity_example %}
type: event_hook
data:
source: "crud"
event: "consumers"
handler: "webhook"
on_change: true
config:
"url": "$WEBHOOK_URL"
{% endentity_example %}


## Configure an Event Hook


For step-by-step guides on configuring Event Hooks see the following docs:

* [Create a Web Hook with {{site.base_gateway}}](/how-to/create-a-webhook-with-kong-gateway/)
* [Push Event Hook information to Slack with {{site.base_gateway}}](/how-to/create-a-custom-webhook-slack-with-kong-gateway/)
* [How to create a log Event Hook with {{site.base_gateway}}](/how-to/create-a-log-event-hook-with-kong-gateway/)
* [Configure an Event Hook to log events with {{site.base_gateway}}](/how-to/create-a-lambda-event-hook-with-kong-gateway/)

88 changes: 88 additions & 0 deletions app/_how-tos/create-a-custom-webhook-slack-with-kong-gateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
title: Push Event Hook information to Slack with {{site.base_gateway}}
content_type: how_to
works_on:
- on-prem
products:
- gateway
entities:
- event-hook
tier: enterprise
tags:
- eventhooks
- webhook
- notifications

tldr:
q: How can I create a custom webhook to push information to Slack using Event Hooks.
a: With an application URL from Slack, you can configure an Event Hook using the `webhook-custom` handler that can `POST` event information to Slack.
prereqs:
inline:
- title: A Slack webhook application
include_content: prereqs/event-hook/slack
- title: cURL
include_content: prereqs/tools/curl
- title: Reload {{site.base_gateway}}
include_content: prereqs/event-hook/restart-kong-gateway
cleanup:
inline:
- title: Destroy the {{site.base_gateway}} container
include_content: cleanup/products/gateway
icon_url: /assets/icons/gateway.svg
related_resources:
- text: Create a webhook with {{site.base_gateway}}
url: /how-to/create-a-webhook-with-kong-gateway/
- text: Configure an Event Hook to log events with {{site.base_gateway}}
url: /how-to/create-a-log-event-hook-with-kong-gateway/
- text: Create an Event Hook that can run custom code with {{site.base_gateway}}
url: /how-to/create-a-lambda-event-hook-with-kong-gateway/

---


## 1. Configure an Event Hook using the `webhook-custom` handler

Using the `webhook-custom` handler, you can configure an Event Hook that listens for events on a source. The `webhook-custom` handler offers a template that you can configure to create a custom webhook. In this tutorial, we will configure an Event Hook that issues a `POST` request when a `crud` event happens on the Consumer entity. That `POST` request will be made to a Slack webhook application containing a custom message describing the event.

curl -X POST http://localhost:8001/event-hooks \
-H "Content-Type: application/json" \
-d '{
"source": "crud",
"event": "consumers",
"handler": "webhook-custom",
"on_change": true,
"config": {
"method": "POST",
"url": "$SLACK_WEBHOOK_URL",
"headers": {
"Content-type": "application/json"
},
"payload": {
"text": "new consumer added"
}
}
}'

Posting this will result in a `200` response. The `config` body in the Event Hook contains information about the webhook that was created:

* **`"method": "POST"`**: The method we are using in the webhook.
* **`"url": "$SLACK_WEBHOOK_URL"`**: The URL of the webhook, in this case we are using the Slack URl that we created and set as an environment variable.
* **`"payload"`**: What this webhook will `POST`.


## 2. Validate the webhook


{:.warning}
> **Important**: Before you can use Event Hooks for the first time, {{site.base_gateway}} needs to be [reloaded](/how-to/restart-kong-gateway-container).


Using the Admin API to create a new Consumer:

```sh
curl -i -X POST http://localhost:8001/consumers \
-d username="my-consumer"
```


Slack will post a message to the channel informing you that a Consumer was added.
92 changes: 92 additions & 0 deletions app/_how-tos/create-a-lambda-event-hook-with-kong-gateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
title: Create an Event Hook that can run custom code with {{site.base_gateway}}
content_type: how_to

entities:
- event-hook
works_on:
- on-prem
products:
- gateway
tier: enterprise

tags:
- eventhooks
- webhook
- notifications
tldr:
q: Can you write code to pass into an Event Hook?
a: The `lambda` Event Hook handler can be used to pass custom Lua code. You can then configure the Event Hook to execute that code on an event.

prereqs:
inline:
- title: cURL
include_content: prereqs/tools/curl
- title: Reload {{site.base_gateway}}
include_content: prereqs/event-hook/restart-kong-gateway
cleanup:
inline:
- title: Destroy the {{site.base_gateway}} container
include_content: cleanup/products/gateway
icon_url: /assets/icons/gateway.svg
related_resources:
- text: Create a webhook with {{site.base_gateway}}
url: /how-to/create-a-webhook-with-kong-gateway/
- text: Configure an Event Hook to log events with {{site.base_gateway}}
url: /how-to/create-a-log-event-hook-with-kong-gateway/
- text: Push Event Hook information to Slack with {{site.base_gateway}}
url: /how-to/create-a-custom-webhook-slack-with-kong-gateway/

---

## 1. Create a lambda Event Hook

A `lambda` Event Hook is an Event Hook that utilizes the `lambda` handler to pass custom code to an Event Hook. Depending on the source and individual event, that code can execute during various stages of the lifecycle of an event. In this guide, you will create an `lambda` Event Hook with custom code that logs an error with a specific message every time you create a Consumer.

Create a lua script to load into the lambda Event Hook.

```lua
return function (data, event, source, pid)
local user = data.entity.username
error("Event Hook on consumer " .. user .. "")
end
```

Create a lambda Event Hook on the `consumers` event, with the `crud` source by creating a `POST` request to the Admin API and passing the code in the request body as an array of strings.

```sh
curl -i -X POST http://localhost:8001/event-hooks \
-H "Content-Type: application/json" \
-d '{
"source": "crud",
"event": "consumers",
"handler": "lambda",
"config": {
"functions": [
"return function (data, event, source, pid) local user = data.entity.username error(\"Event Hook on consumer \" .. user .. \"\") end"
]
}
}'
```



## 2. Validate the webhook

{:.warning}
> **Important**: Before you can use event hooks for the first time, {{site.base_gateway}} needs to be reloaded.

Using the Admin API create a new Consumer:

```sh
curl -i -X POST http://localhost:8001/consumers \
-d username="my-consumer"
```

Review the logs at `/usr/local/kong/logs/error.log` for an update about the creation of this Consumer. The log will look similar to this:

```sh
2024/12/16 21:52:54 [error] 114#0: *153047 [kong] event_hooks.lua:190 [string "return function (data, event, source, pid)..."]:3: Event Hook on consumer my-consumer, context: ngx.timer, client: 172.19.0.1, server: 0.0.0.0:8001
```

In the error logs, you will see the Event Hook, and the error log that resulted from `error("Event Hook on consumer " .. user .. "")`.
Loading
Loading