Skip to content

Commit

Permalink
docs(gateway): dynamic plugin ordering (#3905)
Browse files Browse the repository at this point in the history
* docs(gateway): dynamic plugin ordering

https://konghq.atlassian.net/browse/DOCU-2305

Signed-off-by: Joshua Schmid <[email protected]>

* split plugin ordering doc into two; minor edits

* formatting, phrasing, typo cleanup; pulled 'workspaces' into 'performance limitations'

* docs(gateway): drop kong manager instructions

Signed-off-by: Joshua Schmid <[email protected]>

* grammar, spelling, formatting cleanup; added info about Kong Manager to the overview

* fix typos; improve formatting and phrasing

Co-authored-by: lena.larionova <[email protected]>
  • Loading branch information
jschmid1 and lena-larionova committed Jul 14, 2022
1 parent c73602f commit dd9f100
Show file tree
Hide file tree
Showing 4 changed files with 310 additions and 0 deletions.
6 changes: 6 additions & 0 deletions app/_data/docs_nav_gateway_3.0.x.yml
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ items:

- text: Configure gRPC Plugins
url: /configure/grpc
- text: Dynamic Plugin Ordering
items:
- text: Overview
url: /configure/dynamic-plugin-ordering
- text: Get Started with Dynamic Plugin Ordering
url: /configure/dynamic-plugin-ordering/get-started
- text: GraphQL Quickstart
url: /configure/graphql-quickstart
- text: Logging Reference
Expand Down
197 changes: 197 additions & 0 deletions src/gateway/configure/dynamic-plugin-ordering/get-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
---
title: Get Started with Dynamic Plugin Ordering
badge: enterprise
content_type: how-to
---

Here are some common use cases for [dynamic plugin ordering](/gateway/{{page.kong_version}}/configure/dynamic-plugin-ordering).

## Rate limiting before authentication

Let's say you want to limit the amount of requests against your service and route
*before* Kong requests authentication. You can describe this dependency with the
token `before`.

The following example uses the [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced)
plugin with the [Key Authentication](/hub/kong-inc/key-auth) plugin as the
authentication method.

{% navtabs %}
{% navtab Admin API %}

Call the Admin API on port `8001` and enable the
`rate-limiting` plugin, configuring it to run before `key-auth`:

<!-- codeblock tabs -->
{% navtabs codeblock %}
{% navtab cURL %}
```sh
curl -i -X POST http://<admin-hostname>:8001/plugins \
--data name=rate-limiting \
--data config.minute=5 \
--data config.policy=local \
--data ordering.before.access=key-auth
```
{% endnavtab %}
{% navtab HTTPie %}
```sh
http -f post :8001/plugins \
name=rate-limiting \
config.minute=5 \
config.policy=local \
ordering.before.access=key-auth
```
{% endnavtab %}
{% endnavtabs %}
<!-- end codeblock tabs -->

{% endnavtab %}
{% navtab decK (YAML) %}

1. Add a new `plugins` section to the bottom of your `kong.yaml` file. Enable
`rate-limiting` and set the plugin to run before `key-auth`:

``` yaml
plugins:
- name: rate-limiting
config:
minute: 5
policy: local
ordering:
before:
access:
- key-auth
```

Your file should now look like this:

``` yaml
_format_version: "1.1"
services:
- host: mockbin.org
name: example_service
port: 80
protocol: http
routes:
- name: mocking
paths:
- /mock
strip_path: true
plugins:
- name: rate-limiting
config:
minute: 5
policy: local
ordering:
before:
access:
- key-auth
```

This plugin will be applied globally, which means the rate limiting
applies to all requests, including every Service and Route in the Workspace.

If you pasted the plugin section under an existing Service, Route, or
Consumer, the rate limiting would only apply to that specific
entity.

{:.note}
> **Note**: By default, `enabled` is set to `true` for the plugin. You can
disable the plugin at any time by setting `enabled: false`.

2. Sync the configuration:

``` bash
deck sync
```

{% endnavtab %}
{% endnavtabs %}

## Authentication after request transformation

The following example is similar to running [rate limiting before authentication](#rate-limiting-before-authentication).

For example, you may want to first transform a request, then request authentication
*after* transformation. You can describe this dependency with the token `after`.

Instead of changing the order of the [Request Transformer](/hub/kong-inc/request-transformer)
plugin, you can change the order of the authentication plugin
([Basic Authentication](/hub/kong-inc/basic-auth), in this example).

{% navtabs %}
{% navtab Admin API %}

Call the Admin API on port `8001` and enable the
`basic-auth` plugin, configuring it to run after `request-transformer`:

<!-- codeblock tabs -->
{% navtabs codeblock %}
{% navtab cURL %}
```sh
curl -i -X POST http://<admin-hostname>:8001/plugins \
--data name=basic-auth \
--data ordering.after.access=request-transformer
```
{% endnavtab %}
{% navtab HTTPie %}
```sh
http -f post :8001/plugins \
name=basic-auth \
ordering.before.access=key-auth
```
{% endnavtab %}
{% endnavtabs %}
<!-- end codeblock tabs -->

{% endnavtab %}
{% navtab decK (YAML) %}

1. Add a new `plugins` section to the bottom of your `kong.yaml` file. Enable
`basic-auth` and set the plugin to run after `request-transformer`:

``` yaml
plugins:
- name: basic-auth
config: {}
ordering:
after:
access:
- request-transformer
```

Your file should now look like this:

``` yaml
_format_version: "1.1"
services:
- host: mockbin.org
name: example_service
port: 80
protocol: http
routes:
- name: mocking
paths:
- /mock
strip_path: true
plugins:
- name: basic-auth
config: {}
ordering:
after:
access:
- request-transformer
```

{:.note}
> **Note**: By default, `enabled` is set to `true` for the plugin. You can
disable the plugin at any time by setting `enabled: false`.

2. Sync the configuration:

``` bash
deck sync
```

{% endnavtab %}
{% endnavtabs %}
100 changes: 100 additions & 0 deletions src/gateway/configure/dynamic-plugin-ordering/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: Dynamic Plugin Ordering
badge: enterprise
content_type: explanation
---

The order in which plugins are executed in Kong is determined by their
`static priority`. As the name suggests, this value is _static_ and can't be
easily changed by the user.

You can override the priority for any Kong plugin using each plugin's
`ordering` field. This determines plugin ordering during the `access` phase,
and lets you create _dynamic_ dependencies between plugins.

## Concepts

### Dependency tokens

Use one of the following tokens to describe a dependency to a plugin:

* `before`: The plugin will be executed _before_ a specified plugin or list of plugins.
* `after`: The plugin will be executed _after_ a specified plugin or list of plugins.

### Phases

When a request is processed by {{site.base_gateway}}, it goes through various
[phases](/gateway/latest/plugin-development/custom-logic/#available-contexts),
depending on the configured plugins. You can influence the order in which
plugins are executed for each phase.

Currently, {{site.base_gateway}} supports dynamic plugin ordering in the
`access` phase.

### API

You can use the following API to express dependencies for plugins within a
certain request phase (examples are in decK-formatted YAML):

```yaml
ordering:
$dependency_token:
$supported_phase:
- pluginA
- ...
```
For example, if you want to express that PluginA's `access` phase should
run _before_ PluginB's `access` phase, you would write something like this:

```yaml
PluginA:
ordering:
before:
access:
- PluginB
```

## Known limitations

### Consumer scoping

Consumer-scoped plugins don't support dynamic ordering because consumer mapping
also runs in the access phase. The order of the plugins must be determined
after consumer mapping has happened. {{site.base_gateway}} can't reliably
change the order of the plugins in relation to consumer mapping.

### Cascading deletes & updates

There is no support to detect if a plugin has a dependency to
a deleted plugin, so handle your configuration with care.

### Performance implications

Dynamic plugin ordering requires sorting plugins during a request. This naturally
adds latency to the request. In some cases, this might be compensated for when
you run rate limiting before an expensive authentication plugin.

Re-ordering _any_ plugin in a workspace has performance implications to all
other plugins within the same workspace. If possible, consider offloading plugin
ordering to a separate workspace.

### Validation

Validating dynamic plugin ordering is a non-trivial task and would require
insight into the user's business logic. {{site.base_gateway}} tries to catch
basic mistakes but it can't detect all potentially dangerous configurations.

If using dynamic ordering, manually test all configurations, and handle this
feature with care.

### Kong Manager

Kong Manager doesn't support dynamic plugin ordering configuration through the
UI. Use the Kong Admin API or a declarative configuration file to set
plugin ordering.

## See also

Check out the examples in the
[getting started guide for dynamic plugin ordering](/gateway/{{page.kong_version}}/configure/dynamic-plugin-ordering/get-started).
7 changes: 7 additions & 0 deletions src/gateway/plugin-development/custom-logic.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,13 @@ CustomHandler.PRIORITY = 10
The higher the priority, the sooner your plugin's phases will be executed in
regard to other plugins' phases (such as `:access()`, `:log()`, etc.).

### Kong plugins

All of the plugins bundled with {{site.base_gateway}} have a static priority.
This can be adjusted dynamically using the `ordering` option. See
[Dynamic Plugin Ordering](/gateway/{{page.kong_version}}/configure/dynamic-plugin-ordering)
for more information.

{% navtabs %}
{% navtab Open-source or Free mode %}

Expand Down

0 comments on commit dd9f100

Please sign in to comment.